blob: 33cedf2b04cf6ad4d4109c7d62d454a108b16d21 [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 Deymo535f3b72015-08-07 10:51:32 -070034#include <chromeos/message_loops/base_message_loop.h>
Alex Deymo60ca1a72015-06-18 18:19:15 -070035#include <chromeos/message_loops/message_loop.h>
36#include <chromeos/message_loops/message_loop_utils.h>
Alex Deymo535f3b72015-08-07 10:51:32 -070037#include <chromeos/process.h>
38#include <chromeos/streams/file_stream.h>
39#include <chromeos/streams/stream.h>
Andrew de los Reyes45168102010-11-22 11:13:50 -080040#include <gtest/gtest.h>
41
Gilad Arnold5bb4c902014-04-10 12:32:13 -070042#include "update_engine/fake_system_state.h"
Gilad Arnold9bedeb52011-11-17 16:19:57 -080043#include "update_engine/http_common.h"
rspangler@google.com49fdf182009-10-10 00:57:34 +000044#include "update_engine/libcurl_http_fetcher.h"
45#include "update_engine/mock_http_fetcher.h"
Andrew de los Reyes819fef22010-12-17 11:33:58 -080046#include "update_engine/multi_range_http_fetcher.h"
Andrew de los Reyes45168102010-11-22 11:13:50 -080047#include "update_engine/proxy_resolver.h"
Alex Deymo535f3b72015-08-07 10:51:32 -070048#include "update_engine/test_utils.h"
Jay Srinivasan08fce042012-06-07 16:31:01 -070049#include "update_engine/utils.h"
rspangler@google.com49fdf182009-10-10 00:57:34 +000050
Alex Deymo60ca1a72015-06-18 18:19:15 -070051using chromeos::MessageLoop;
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -070052using std::make_pair;
Andrew de los Reyes819fef22010-12-17 11:33:58 -080053using std::pair;
adlr@google.comc98a7ed2009-12-04 18:54:03 +000054using std::string;
Ben Chan02f7c1d2014-10-18 15:18:02 -070055using std::unique_ptr;
adlr@google.comc98a7ed2009-12-04 18:54:03 +000056using std::vector;
57
Gilad Arnold9bedeb52011-11-17 16:19:57 -080058namespace {
59
60const int kBigLength = 100000;
61const int kMediumLength = 1000;
Gilad Arnold34bf1ee2012-02-09 16:16:02 -080062const int kFlakyTruncateLength = 29000;
63const int kFlakySleepEvery = 3;
Gilad Arnold9bedeb52011-11-17 16:19:57 -080064const int kFlakySleepSecs = 10;
65
66} // namespace
67
rspangler@google.com49fdf182009-10-10 00:57:34 +000068namespace chromeos_update_engine {
69
Gilad Arnold9bedeb52011-11-17 16:19:57 -080070static const char *kUnusedUrl = "unused://unused";
71
Gilad Arnoldb6c562a2013-07-01 02:19:26 -070072static inline string LocalServerUrlForPath(in_port_t port,
73 const string& path) {
Alex Vakulenko75039d72014-03-25 12:36:28 -070074 string port_str = (port ? base::StringPrintf(":%hu", port) : "");
Gilad Arnoldb6c562a2013-07-01 02:19:26 -070075 return base::StringPrintf("http://127.0.0.1%s%s", port_str.c_str(),
76 path.c_str());
rspangler@google.com49fdf182009-10-10 00:57:34 +000077}
78
Gilad Arnold9bedeb52011-11-17 16:19:57 -080079//
80// Class hierarchy for HTTP server implementations.
81//
82
83class HttpServer {
rspangler@google.com49fdf182009-10-10 00:57:34 +000084 public:
Gilad Arnold9bedeb52011-11-17 16:19:57 -080085 // This makes it an abstract class (dirty but works).
86 virtual ~HttpServer() = 0;
87
Gilad Arnoldb6c562a2013-07-01 02:19:26 -070088 virtual in_port_t GetPort() const {
89 return 0;
90 }
91
rspangler@google.com49fdf182009-10-10 00:57:34 +000092 bool started_;
93};
94
Gilad Arnold9bedeb52011-11-17 16:19:57 -080095HttpServer::~HttpServer() {}
rspangler@google.com49fdf182009-10-10 00:57:34 +000096
Gilad Arnold9bedeb52011-11-17 16:19:57 -080097
98class NullHttpServer : public HttpServer {
rspangler@google.com49fdf182009-10-10 00:57:34 +000099 public:
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800100 NullHttpServer() {
101 started_ = true;
rspangler@google.com49fdf182009-10-10 00:57:34 +0000102 }
rspangler@google.com49fdf182009-10-10 00:57:34 +0000103};
104
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800105
106class PythonHttpServer : public HttpServer {
rspangler@google.com49fdf182009-10-10 00:57:34 +0000107 public:
Alex Deymo535f3b72015-08-07 10:51:32 -0700108 PythonHttpServer() : port_(0) {
rspangler@google.com49fdf182009-10-10 00:57:34 +0000109 started_ = false;
Gilad Arnoldb6c562a2013-07-01 02:19:26 -0700110
111 // Spawn the server process.
Alex Deymo535f3b72015-08-07 10:51:32 -0700112 unique_ptr<chromeos::Process> http_server(new chromeos::ProcessImpl());
113 base::FilePath test_server_path =
114 test_utils::GetBuildArtifactsPath().Append("test_http_server");
115 http_server->AddArg(test_server_path.value());
116 http_server->RedirectUsingPipe(STDOUT_FILENO, false);
117
118 if (!http_server->Start()) {
119 ADD_FAILURE() << "failed to spawn http server process";
rspangler@google.com49fdf182009-10-10 00:57:34 +0000120 return;
121 }
Alex Deymo535f3b72015-08-07 10:51:32 -0700122 LOG(INFO) << "started http server with pid " << http_server->pid();
Gilad Arnoldb6c562a2013-07-01 02:19:26 -0700123
124 // Wait for server to begin accepting connections, obtain its port.
Alex Deymo535f3b72015-08-07 10:51:32 -0700125 chromeos::StreamPtr stdout = chromeos::FileStream::FromFileDescriptor(
126 http_server->GetPipe(STDOUT_FILENO), false /* own */, nullptr);
127 if (!stdout)
128 return;
129
130 vector<char> buf(128);
131 string line;
132 while (line.find('\n') == string::npos) {
133 size_t read;
134 if (!stdout->ReadBlocking(buf.data(), buf.size(), &read, nullptr)) {
135 ADD_FAILURE() << "error reading http server stdout";
136 return;
Gilad Arnoldb6c562a2013-07-01 02:19:26 -0700137 }
Alex Deymo535f3b72015-08-07 10:51:32 -0700138 line.append(buf.data(), read);
139 if (read == 0)
140 break;
141 }
142 // Parse the port from the output line.
143 const size_t listening_msg_prefix_len = strlen(kServerListeningMsgPrefix);
144 if (line.size() < listening_msg_prefix_len) {
145 ADD_FAILURE() << "server output too short";
Gilad Arnoldb6c562a2013-07-01 02:19:26 -0700146 return;
147 }
148
Alex Deymo535f3b72015-08-07 10:51:32 -0700149 EXPECT_EQ(kServerListeningMsgPrefix,
150 line.substr(0, listening_msg_prefix_len));
151 string port_str = line.substr(listening_msg_prefix_len);
152 port_str.resize(port_str.find('\n'));
153 EXPECT_TRUE(base::StringToUint(port_str, &port_));
154
Andrew de los Reyes3270f742010-07-15 22:28:14 -0700155 started_ = true;
Gilad Arnoldb6c562a2013-07-01 02:19:26 -0700156 LOG(INFO) << "server running, listening on port " << port_;
Alex Deymo535f3b72015-08-07 10:51:32 -0700157
158 // Any failure before this point will SIGKILL the test server if started
159 // when the |http_server| goes out of scope.
160 http_server_ = std::move(http_server);
rspangler@google.com49fdf182009-10-10 00:57:34 +0000161 }
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800162
rspangler@google.com49fdf182009-10-10 00:57:34 +0000163 ~PythonHttpServer() {
Gilad Arnoldb6c562a2013-07-01 02:19:26 -0700164 // If there's no process, do nothing.
Alex Deymo535f3b72015-08-07 10:51:32 -0700165 if (!http_server_)
rspangler@google.com49fdf182009-10-10 00:57:34 +0000166 return;
Alex Deymo535f3b72015-08-07 10:51:32 -0700167 // Wait up to 10 seconds for the process to finish. Destroying the process
168 // will kill it with a SIGKILL otherwise.
169 http_server_->Kill(SIGTERM, 10);
rspangler@google.com49fdf182009-10-10 00:57:34 +0000170 }
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800171
Alex Deymo610277e2014-11-11 21:18:11 -0800172 in_port_t GetPort() const override {
Gilad Arnoldb6c562a2013-07-01 02:19:26 -0700173 return port_;
174 }
175
176 private:
Gilad Arnoldb6c562a2013-07-01 02:19:26 -0700177 static const char* kServerListeningMsgPrefix;
178
Alex Deymo535f3b72015-08-07 10:51:32 -0700179 unique_ptr<chromeos::Process> http_server_;
180 unsigned int port_;
rspangler@google.com49fdf182009-10-10 00:57:34 +0000181};
182
Gilad Arnoldb6c562a2013-07-01 02:19:26 -0700183const char* PythonHttpServer::kServerListeningMsgPrefix = "listening on port ";
184
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800185//
186// Class hierarchy for HTTP fetcher test wrappers.
187//
188
189class AnyHttpFetcherTest {
rspangler@google.com49fdf182009-10-10 00:57:34 +0000190 public:
Chris Sosa77f79e82014-06-02 18:16:24 -0700191 AnyHttpFetcherTest() {}
Alex Deymoc4acdf42014-05-28 21:07:10 -0700192 virtual ~AnyHttpFetcherTest() {}
Jay Srinivasan43488792012-06-19 00:25:31 -0700193
Alex Deymo7984bf02014-04-02 20:41:57 -0700194 virtual HttpFetcher* NewLargeFetcher(size_t num_proxies) = 0;
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800195 HttpFetcher* NewLargeFetcher() {
196 return NewLargeFetcher(1);
197 }
198
199 virtual HttpFetcher* NewSmallFetcher(size_t num_proxies) = 0;
200 HttpFetcher* NewSmallFetcher() {
201 return NewSmallFetcher(1);
202 }
203
Gilad Arnoldb6c562a2013-07-01 02:19:26 -0700204 virtual string BigUrl(in_port_t port) const { return kUnusedUrl; }
205 virtual string SmallUrl(in_port_t port) const { return kUnusedUrl; }
206 virtual string ErrorUrl(in_port_t port) const { return kUnusedUrl; }
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800207
208 virtual bool IsMock() const = 0;
209 virtual bool IsMulti() const = 0;
210
211 virtual void IgnoreServerAborting(HttpServer* server) const {}
212
Alex Deymo60ca1a72015-06-18 18:19:15 -0700213 virtual HttpServer* CreateServer() = 0;
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800214
215 protected:
216 DirectProxyResolver proxy_resolver_;
Gilad Arnold5bb4c902014-04-10 12:32:13 -0700217 FakeSystemState fake_system_state_;
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800218};
219
220class MockHttpFetcherTest : public AnyHttpFetcherTest {
221 public:
222 // Necessary to unhide the definition in the base class.
223 using AnyHttpFetcherTest::NewLargeFetcher;
Alex Deymo610277e2014-11-11 21:18:11 -0800224 HttpFetcher* NewLargeFetcher(size_t num_proxies) override {
Alex Vakulenkof68bbbc2015-02-09 12:53:18 -0800225 chromeos::Blob big_data(1000000);
Alex Vakulenkod2779df2014-06-16 13:19:00 -0700226 CHECK_GT(num_proxies, 0u);
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800227 proxy_resolver_.set_num_proxies(num_proxies);
228 return new MockHttpFetcher(
229 big_data.data(),
230 big_data.size(),
231 reinterpret_cast<ProxyResolver*>(&proxy_resolver_));
232 }
233
234 // Necessary to unhide the definition in the base class.
235 using AnyHttpFetcherTest::NewSmallFetcher;
Alex Deymo610277e2014-11-11 21:18:11 -0800236 HttpFetcher* NewSmallFetcher(size_t num_proxies) override {
Alex Vakulenkod2779df2014-06-16 13:19:00 -0700237 CHECK_GT(num_proxies, 0u);
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800238 proxy_resolver_.set_num_proxies(num_proxies);
239 return new MockHttpFetcher(
240 "x",
241 1,
242 reinterpret_cast<ProxyResolver*>(&proxy_resolver_));
243 }
244
Alex Deymo610277e2014-11-11 21:18:11 -0800245 bool IsMock() const override { return true; }
246 bool IsMulti() const override { return false; }
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800247
Alex Deymo60ca1a72015-06-18 18:19:15 -0700248 HttpServer* CreateServer() override {
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800249 return new NullHttpServer;
250 }
251};
252
253class LibcurlHttpFetcherTest : public AnyHttpFetcherTest {
254 public:
255 // Necessary to unhide the definition in the base class.
256 using AnyHttpFetcherTest::NewLargeFetcher;
Alex Deymo610277e2014-11-11 21:18:11 -0800257 HttpFetcher* NewLargeFetcher(size_t num_proxies) override {
Alex Vakulenkod2779df2014-06-16 13:19:00 -0700258 CHECK_GT(num_proxies, 0u);
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800259 proxy_resolver_.set_num_proxies(num_proxies);
Andrew de los Reyes45168102010-11-22 11:13:50 -0800260 LibcurlHttpFetcher *ret = new
Jay Srinivasan08fce042012-06-07 16:31:01 -0700261 LibcurlHttpFetcher(reinterpret_cast<ProxyResolver*>(&proxy_resolver_),
Nam T. Nguyen7d623eb2014-05-13 16:06:28 -0700262 &fake_system_state_);
Darin Petkovb83371f2010-08-17 09:34:49 -0700263 // Speed up test execution.
264 ret->set_idle_seconds(1);
265 ret->set_retry_seconds(1);
Gilad Arnold5bb4c902014-04-10 12:32:13 -0700266 fake_system_state_.fake_hardware()->SetIsOfficialBuild(false);
rspangler@google.com49fdf182009-10-10 00:57:34 +0000267 return ret;
268 }
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800269
270 // Necessary to unhide the definition in the base class.
271 using AnyHttpFetcherTest::NewSmallFetcher;
Alex Deymo610277e2014-11-11 21:18:11 -0800272 HttpFetcher* NewSmallFetcher(size_t num_proxies) override {
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800273 return NewLargeFetcher(num_proxies);
rspangler@google.com49fdf182009-10-10 00:57:34 +0000274 }
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800275
Alex Deymo610277e2014-11-11 21:18:11 -0800276 string BigUrl(in_port_t port) const override {
Gilad Arnoldb6c562a2013-07-01 02:19:26 -0700277 return LocalServerUrlForPath(port,
278 base::StringPrintf("/download/%d",
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800279 kBigLength));
rspangler@google.com49fdf182009-10-10 00:57:34 +0000280 }
Alex Deymo610277e2014-11-11 21:18:11 -0800281 string SmallUrl(in_port_t port) const override {
Gilad Arnoldb6c562a2013-07-01 02:19:26 -0700282 return LocalServerUrlForPath(port, "/foo");
rspangler@google.com49fdf182009-10-10 00:57:34 +0000283 }
Alex Deymo610277e2014-11-11 21:18:11 -0800284 string ErrorUrl(in_port_t port) const override {
Gilad Arnoldb6c562a2013-07-01 02:19:26 -0700285 return LocalServerUrlForPath(port, "/error");
Gilad Arnold48085ba2011-11-16 09:36:08 -0800286 }
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800287
Alex Deymo610277e2014-11-11 21:18:11 -0800288 bool IsMock() const override { return false; }
289 bool IsMulti() const override { return false; }
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800290
Alex Deymo610277e2014-11-11 21:18:11 -0800291 void IgnoreServerAborting(HttpServer* server) const override {
Gilad Arnoldb6c562a2013-07-01 02:19:26 -0700292 // Nothing to do.
Andrew de los Reyes08c4e272010-04-15 14:02:17 -0700293 }
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800294
Alex Deymo60ca1a72015-06-18 18:19:15 -0700295 HttpServer* CreateServer() override {
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800296 return new PythonHttpServer;
297 }
rspangler@google.com49fdf182009-10-10 00:57:34 +0000298};
299
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800300class MultiRangeHttpFetcherTest : public LibcurlHttpFetcherTest {
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -0700301 public:
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800302 // Necessary to unhide the definition in the base class.
303 using AnyHttpFetcherTest::NewLargeFetcher;
Alex Deymo610277e2014-11-11 21:18:11 -0800304 HttpFetcher* NewLargeFetcher(size_t num_proxies) override {
Alex Vakulenkod2779df2014-06-16 13:19:00 -0700305 CHECK_GT(num_proxies, 0u);
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800306 proxy_resolver_.set_num_proxies(num_proxies);
Andrew de los Reyes819fef22010-12-17 11:33:58 -0800307 ProxyResolver* resolver =
308 reinterpret_cast<ProxyResolver*>(&proxy_resolver_);
Gilad Arnold7c04e762012-05-23 10:54:02 -0700309 MultiRangeHttpFetcher *ret =
310 new MultiRangeHttpFetcher(
Nam T. Nguyen7d623eb2014-05-13 16:06:28 -0700311 new LibcurlHttpFetcher(resolver, &fake_system_state_));
Andrew de los Reyes819fef22010-12-17 11:33:58 -0800312 ret->ClearRanges();
Gilad Arnolde4ad2502011-12-29 17:08:54 -0800313 ret->AddRange(0);
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -0700314 // Speed up test execution.
315 ret->set_idle_seconds(1);
316 ret->set_retry_seconds(1);
Gilad Arnold5bb4c902014-04-10 12:32:13 -0700317 fake_system_state_.fake_hardware()->SetIsOfficialBuild(false);
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -0700318 return ret;
319 }
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800320
321 // Necessary to unhide the definition in the base class.
322 using AnyHttpFetcherTest::NewSmallFetcher;
Alex Deymo610277e2014-11-11 21:18:11 -0800323 HttpFetcher* NewSmallFetcher(size_t num_proxies) override {
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800324 return NewLargeFetcher(num_proxies);
325 }
326
Alex Deymo610277e2014-11-11 21:18:11 -0800327 bool IsMulti() const override { return true; }
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -0700328};
329
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800330
331//
332// Infrastructure for type tests of HTTP fetcher.
333// See: http://code.google.com/p/googletest/wiki/AdvancedGuide#Typed_Tests
334//
335
336// Fixture class template. We use an explicit constraint to guarantee that it
337// can only be instantiated with an AnyHttpFetcherTest type, see:
338// http://www2.research.att.com/~bs/bs_faq2.html#constraints
339template <typename T>
340class HttpFetcherTest : public ::testing::Test {
341 public:
Alex Deymo535f3b72015-08-07 10:51:32 -0700342 base::MessageLoopForIO base_loop_;
343 chromeos::BaseMessageLoop loop_{&base_loop_};
Alex Deymo60ca1a72015-06-18 18:19:15 -0700344
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800345 T test_;
346
Alex Deymo60ca1a72015-06-18 18:19:15 -0700347 protected:
348 HttpFetcherTest() {
349 loop_.SetAsCurrent();
350 }
351
352 void TearDown() override {
353 EXPECT_EQ(0, chromeos::MessageLoopRunMaxIterations(&loop_, 1));
354 }
355
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800356 private:
Alex Deymo60ca1a72015-06-18 18:19:15 -0700357 static void TypeConstraint(T* a) {
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800358 AnyHttpFetcherTest *b = a;
Alex Vakulenkod2779df2014-06-16 13:19:00 -0700359 if (b == 0) // Silence compiler warning of unused variable.
Yunlian Jiang2dac5762013-04-12 09:53:09 -0700360 *b = a;
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800361 }
362};
363
364// Test case types list.
365typedef ::testing::Types<LibcurlHttpFetcherTest,
366 MockHttpFetcherTest,
367 MultiRangeHttpFetcherTest> HttpFetcherTestTypes;
rspangler@google.com49fdf182009-10-10 00:57:34 +0000368TYPED_TEST_CASE(HttpFetcherTest, HttpFetcherTestTypes);
369
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800370
rspangler@google.com49fdf182009-10-10 00:57:34 +0000371namespace {
372class HttpFetcherTestDelegate : public HttpFetcherDelegate {
adlr@google.comc98a7ed2009-12-04 18:54:03 +0000373 public:
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800374 HttpFetcherTestDelegate() :
Gilad Arnold48085ba2011-11-16 09:36:08 -0800375 is_expect_error_(false), times_transfer_complete_called_(0),
376 times_transfer_terminated_called_(0), times_received_bytes_called_(0) {}
377
Alex Deymo610277e2014-11-11 21:18:11 -0800378 void ReceivedBytes(HttpFetcher* /* fetcher */,
Alex Vakulenkof68bbbc2015-02-09 12:53:18 -0800379 const void* /* bytes */, size_t /* length */) override {
Gilad Arnold48085ba2011-11-16 09:36:08 -0800380 // Update counters
381 times_received_bytes_called_++;
rspangler@google.com49fdf182009-10-10 00:57:34 +0000382 }
Gilad Arnold48085ba2011-11-16 09:36:08 -0800383
Alex Deymo610277e2014-11-11 21:18:11 -0800384 void TransferComplete(HttpFetcher* fetcher, bool successful) override {
Gilad Arnold48085ba2011-11-16 09:36:08 -0800385 if (is_expect_error_)
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800386 EXPECT_EQ(kHttpResponseNotFound, fetcher->http_response_code());
Gilad Arnold48085ba2011-11-16 09:36:08 -0800387 else
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800388 EXPECT_EQ(kHttpResponseOk, fetcher->http_response_code());
Alex Deymo60ca1a72015-06-18 18:19:15 -0700389 MessageLoop::current()->BreakLoop();
Gilad Arnold48085ba2011-11-16 09:36:08 -0800390
391 // Update counter
392 times_transfer_complete_called_++;
rspangler@google.com49fdf182009-10-10 00:57:34 +0000393 }
Gilad Arnold48085ba2011-11-16 09:36:08 -0800394
Alex Deymo610277e2014-11-11 21:18:11 -0800395 void TransferTerminated(HttpFetcher* fetcher) override {
Darin Petkov9ce452b2010-11-17 14:33:28 -0800396 ADD_FAILURE();
Gilad Arnold48085ba2011-11-16 09:36:08 -0800397 times_transfer_terminated_called_++;
Darin Petkov9ce452b2010-11-17 14:33:28 -0800398 }
Gilad Arnold48085ba2011-11-16 09:36:08 -0800399
Gilad Arnold48085ba2011-11-16 09:36:08 -0800400 // Are we expecting an error response? (default: no)
401 bool is_expect_error_;
402
403 // Counters for callback invocations.
404 int times_transfer_complete_called_;
405 int times_transfer_terminated_called_;
406 int times_received_bytes_called_;
rspangler@google.com49fdf182009-10-10 00:57:34 +0000407};
adlr@google.comc98a7ed2009-12-04 18:54:03 +0000408
adlr@google.comc98a7ed2009-12-04 18:54:03 +0000409
Alex Deymo60ca1a72015-06-18 18:19:15 -0700410void StartTransfer(HttpFetcher* http_fetcher, const string& url) {
411 http_fetcher->BeginTransfer(url);
adlr@google.comc98a7ed2009-12-04 18:54:03 +0000412}
Alex Vakulenkod2779df2014-06-16 13:19:00 -0700413} // namespace
rspangler@google.com49fdf182009-10-10 00:57:34 +0000414
415TYPED_TEST(HttpFetcherTest, SimpleTest) {
Alex Deymo60ca1a72015-06-18 18:19:15 -0700416 HttpFetcherTestDelegate delegate;
417 unique_ptr<HttpFetcher> fetcher(this->test_.NewSmallFetcher());
418 fetcher->set_delegate(&delegate);
rspangler@google.com49fdf182009-10-10 00:57:34 +0000419
Alex Deymo60ca1a72015-06-18 18:19:15 -0700420 unique_ptr<HttpServer> server(this->test_.CreateServer());
421 ASSERT_TRUE(server->started_);
rspangler@google.com49fdf182009-10-10 00:57:34 +0000422
Alex Deymo60ca1a72015-06-18 18:19:15 -0700423 this->loop_.PostTask(FROM_HERE, base::Bind(
424 StartTransfer,
425 fetcher.get(),
426 this->test_.SmallUrl(server->GetPort())));
427 this->loop_.Run();
rspangler@google.com49fdf182009-10-10 00:57:34 +0000428}
429
Andrew de los Reyes3270f742010-07-15 22:28:14 -0700430TYPED_TEST(HttpFetcherTest, SimpleBigTest) {
Alex Deymo60ca1a72015-06-18 18:19:15 -0700431 HttpFetcherTestDelegate delegate;
432 unique_ptr<HttpFetcher> fetcher(this->test_.NewLargeFetcher());
433 fetcher->set_delegate(&delegate);
Andrew de los Reyes3270f742010-07-15 22:28:14 -0700434
Alex Deymo60ca1a72015-06-18 18:19:15 -0700435 unique_ptr<HttpServer> server(this->test_.CreateServer());
436 ASSERT_TRUE(server->started_);
Andrew de los Reyes3270f742010-07-15 22:28:14 -0700437
Alex Deymo60ca1a72015-06-18 18:19:15 -0700438 this->loop_.PostTask(FROM_HERE, base::Bind(
439 StartTransfer,
440 fetcher.get(),
441 this->test_.BigUrl(server->GetPort())));
442 this->loop_.Run();
Andrew de los Reyes3270f742010-07-15 22:28:14 -0700443}
444
Gilad Arnold48085ba2011-11-16 09:36:08 -0800445// Issue #9648: when server returns an error HTTP response, the fetcher needs to
446// terminate transfer prematurely, rather than try to process the error payload.
447TYPED_TEST(HttpFetcherTest, ErrorTest) {
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800448 if (this->test_.IsMock() || this->test_.IsMulti())
Gilad Arnold48085ba2011-11-16 09:36:08 -0800449 return;
Alex Deymo60ca1a72015-06-18 18:19:15 -0700450 HttpFetcherTestDelegate delegate;
Gilad Arnold48085ba2011-11-16 09:36:08 -0800451
Alex Deymo60ca1a72015-06-18 18:19:15 -0700452 // Delegate should expect an error response.
453 delegate.is_expect_error_ = true;
Gilad Arnold48085ba2011-11-16 09:36:08 -0800454
Alex Deymo60ca1a72015-06-18 18:19:15 -0700455 unique_ptr<HttpFetcher> fetcher(this->test_.NewSmallFetcher());
456 fetcher->set_delegate(&delegate);
Gilad Arnold48085ba2011-11-16 09:36:08 -0800457
Alex Deymo60ca1a72015-06-18 18:19:15 -0700458 unique_ptr<HttpServer> server(this->test_.CreateServer());
459 ASSERT_TRUE(server->started_);
Gilad Arnold48085ba2011-11-16 09:36:08 -0800460
Alex Deymo60ca1a72015-06-18 18:19:15 -0700461 this->loop_.PostTask(FROM_HERE, base::Bind(
462 StartTransfer,
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800463 fetcher.get(),
Alex Deymo60ca1a72015-06-18 18:19:15 -0700464 this->test_.ErrorUrl(server->GetPort())));
465 this->loop_.Run();
Gilad Arnold48085ba2011-11-16 09:36:08 -0800466
Alex Deymo60ca1a72015-06-18 18:19:15 -0700467 // Make sure that no bytes were received.
468 CHECK_EQ(delegate.times_received_bytes_called_, 0);
469 CHECK_EQ(fetcher->GetBytesDownloaded(), static_cast<size_t>(0));
Gilad Arnold48085ba2011-11-16 09:36:08 -0800470
Alex Deymo60ca1a72015-06-18 18:19:15 -0700471 // Make sure that transfer completion was signaled once, and no termination
472 // was signaled.
473 CHECK_EQ(delegate.times_transfer_complete_called_, 1);
474 CHECK_EQ(delegate.times_transfer_terminated_called_, 0);
Gilad Arnold48085ba2011-11-16 09:36:08 -0800475}
476
rspangler@google.com49fdf182009-10-10 00:57:34 +0000477namespace {
478class PausingHttpFetcherTestDelegate : public HttpFetcherDelegate {
479 public:
Alex Deymo610277e2014-11-11 21:18:11 -0800480 void ReceivedBytes(HttpFetcher* fetcher,
Alex Vakulenkof68bbbc2015-02-09 12:53:18 -0800481 const void* /* bytes */, size_t /* length */) override {
rspangler@google.com49fdf182009-10-10 00:57:34 +0000482 CHECK(!paused_);
483 paused_ = true;
484 fetcher->Pause();
rspangler@google.com49fdf182009-10-10 00:57:34 +0000485 }
Alex Deymo610277e2014-11-11 21:18:11 -0800486 void TransferComplete(HttpFetcher* fetcher, bool successful) override {
Alex Deymo60ca1a72015-06-18 18:19:15 -0700487 MessageLoop::current()->BreakLoop();
rspangler@google.com49fdf182009-10-10 00:57:34 +0000488 }
Alex Deymo610277e2014-11-11 21:18:11 -0800489 void TransferTerminated(HttpFetcher* fetcher) override {
Darin Petkov9ce452b2010-11-17 14:33:28 -0800490 ADD_FAILURE();
491 }
rspangler@google.com49fdf182009-10-10 00:57:34 +0000492 void Unpause() {
493 CHECK(paused_);
494 paused_ = false;
495 fetcher_->Unpause();
rspangler@google.com49fdf182009-10-10 00:57:34 +0000496 }
497 bool paused_;
498 HttpFetcher* fetcher_;
rspangler@google.com49fdf182009-10-10 00:57:34 +0000499};
500
Alex Deymo60ca1a72015-06-18 18:19:15 -0700501void UnpausingTimeoutCallback(PausingHttpFetcherTestDelegate* delegate,
502 MessageLoop::TaskId* my_id) {
rspangler@google.com49fdf182009-10-10 00:57:34 +0000503 if (delegate->paused_)
504 delegate->Unpause();
Alex Deymo60ca1a72015-06-18 18:19:15 -0700505 // Update the task id with the new scheduled callback.
506 *my_id = MessageLoop::current()->PostDelayedTask(
507 FROM_HERE,
508 base::Bind(&UnpausingTimeoutCallback, delegate, my_id),
509 base::TimeDelta::FromMilliseconds(200));
rspangler@google.com49fdf182009-10-10 00:57:34 +0000510}
Alex Vakulenkod2779df2014-06-16 13:19:00 -0700511} // namespace
rspangler@google.com49fdf182009-10-10 00:57:34 +0000512
513TYPED_TEST(HttpFetcherTest, PauseTest) {
rspangler@google.com49fdf182009-10-10 00:57:34 +0000514 {
515 PausingHttpFetcherTestDelegate delegate;
Ben Chan02f7c1d2014-10-18 15:18:02 -0700516 unique_ptr<HttpFetcher> fetcher(this->test_.NewLargeFetcher());
rspangler@google.com49fdf182009-10-10 00:57:34 +0000517 delegate.paused_ = false;
rspangler@google.com49fdf182009-10-10 00:57:34 +0000518 delegate.fetcher_ = fetcher.get();
519 fetcher->set_delegate(&delegate);
520
Ben Chan02f7c1d2014-10-18 15:18:02 -0700521 unique_ptr<HttpServer> server(this->test_.CreateServer());
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800522 ASSERT_TRUE(server->started_);
Andrew de los Reyesf3ed8e72011-02-16 10:35:46 -0800523
Alex Deymo60ca1a72015-06-18 18:19:15 -0700524 MessageLoop::TaskId callback_id;
525 callback_id = this->loop_.PostDelayedTask(
526 FROM_HERE,
527 base::Bind(&UnpausingTimeoutCallback, &delegate, &callback_id),
528 base::TimeDelta::FromMilliseconds(200));
Gilad Arnoldb6c562a2013-07-01 02:19:26 -0700529 fetcher->BeginTransfer(this->test_.BigUrl(server->GetPort()));
rspangler@google.com49fdf182009-10-10 00:57:34 +0000530
Alex Deymo60ca1a72015-06-18 18:19:15 -0700531 this->loop_.Run();
532 EXPECT_TRUE(this->loop_.CancelTask(callback_id));
rspangler@google.com49fdf182009-10-10 00:57:34 +0000533 }
rspangler@google.com49fdf182009-10-10 00:57:34 +0000534}
535
536namespace {
537class AbortingHttpFetcherTestDelegate : public HttpFetcherDelegate {
538 public:
Alex Deymo610277e2014-11-11 21:18:11 -0800539 void ReceivedBytes(HttpFetcher* fetcher,
Alex Vakulenkof68bbbc2015-02-09 12:53:18 -0800540 const void* bytes, size_t length) override {}
Alex Deymo610277e2014-11-11 21:18:11 -0800541 void TransferComplete(HttpFetcher* fetcher, bool successful) override {
Darin Petkov9ce452b2010-11-17 14:33:28 -0800542 ADD_FAILURE(); // We should never get here
Alex Deymo60ca1a72015-06-18 18:19:15 -0700543 MessageLoop::current()->BreakLoop();
rspangler@google.com49fdf182009-10-10 00:57:34 +0000544 }
Alex Deymo610277e2014-11-11 21:18:11 -0800545 void TransferTerminated(HttpFetcher* fetcher) override {
Darin Petkov9ce452b2010-11-17 14:33:28 -0800546 EXPECT_EQ(fetcher, fetcher_.get());
547 EXPECT_FALSE(once_);
548 EXPECT_TRUE(callback_once_);
549 callback_once_ = false;
Alex Deymoc4acdf42014-05-28 21:07:10 -0700550 // The fetcher could have a callback scheduled on the ProxyResolver that
551 // can fire after this callback. We wait until the end of the test to
552 // delete the fetcher.
Andrew de los Reyes819fef22010-12-17 11:33:58 -0800553 }
rspangler@google.com49fdf182009-10-10 00:57:34 +0000554 void TerminateTransfer() {
555 CHECK(once_);
556 once_ = false;
557 fetcher_->TerminateTransfer();
558 }
559 void EndLoop() {
Alex Deymo60ca1a72015-06-18 18:19:15 -0700560 MessageLoop::current()->BreakLoop();
rspangler@google.com49fdf182009-10-10 00:57:34 +0000561 }
562 bool once_;
Darin Petkov9ce452b2010-11-17 14:33:28 -0800563 bool callback_once_;
Ben Chan02f7c1d2014-10-18 15:18:02 -0700564 unique_ptr<HttpFetcher> fetcher_;
rspangler@google.com49fdf182009-10-10 00:57:34 +0000565};
566
Alex Deymo60ca1a72015-06-18 18:19:15 -0700567void AbortingTimeoutCallback(AbortingHttpFetcherTestDelegate* delegate,
568 MessageLoop::TaskId* my_id) {
rspangler@google.com49fdf182009-10-10 00:57:34 +0000569 if (delegate->once_) {
570 delegate->TerminateTransfer();
Alex Deymo60ca1a72015-06-18 18:19:15 -0700571 *my_id = MessageLoop::current()->PostTask(
572 FROM_HERE,
573 base::Bind(AbortingTimeoutCallback, delegate, my_id));
rspangler@google.com49fdf182009-10-10 00:57:34 +0000574 } else {
575 delegate->EndLoop();
Alex Deymo60ca1a72015-06-18 18:19:15 -0700576 *my_id = MessageLoop::kTaskIdNull;
rspangler@google.com49fdf182009-10-10 00:57:34 +0000577 }
578}
Alex Vakulenkod2779df2014-06-16 13:19:00 -0700579} // namespace
rspangler@google.com49fdf182009-10-10 00:57:34 +0000580
581TYPED_TEST(HttpFetcherTest, AbortTest) {
Alex Deymo60ca1a72015-06-18 18:19:15 -0700582 AbortingHttpFetcherTestDelegate delegate;
583 delegate.fetcher_.reset(this->test_.NewLargeFetcher());
584 delegate.once_ = true;
585 delegate.callback_once_ = true;
586 delegate.fetcher_->set_delegate(&delegate);
rspangler@google.com49fdf182009-10-10 00:57:34 +0000587
Alex Deymo60ca1a72015-06-18 18:19:15 -0700588 unique_ptr<HttpServer> server(this->test_.CreateServer());
589 this->test_.IgnoreServerAborting(server.get());
590 ASSERT_TRUE(server->started_);
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800591
Alex Deymo60ca1a72015-06-18 18:19:15 -0700592 MessageLoop::TaskId task_id = MessageLoop::kTaskIdNull;
rspangler@google.com49fdf182009-10-10 00:57:34 +0000593
Alex Deymo60ca1a72015-06-18 18:19:15 -0700594 task_id = this->loop_.PostTask(
595 FROM_HERE,
596 base::Bind(AbortingTimeoutCallback, &delegate, &task_id));
597 delegate.fetcher_->BeginTransfer(this->test_.BigUrl(server->GetPort()));
598
599 this->loop_.Run();
600 CHECK(!delegate.once_);
601 CHECK(!delegate.callback_once_);
602 this->loop_.CancelTask(task_id);
rspangler@google.com49fdf182009-10-10 00:57:34 +0000603}
604
adlr@google.comc98a7ed2009-12-04 18:54:03 +0000605namespace {
606class FlakyHttpFetcherTestDelegate : public HttpFetcherDelegate {
607 public:
Alex Deymo610277e2014-11-11 21:18:11 -0800608 void ReceivedBytes(HttpFetcher* fetcher,
Alex Vakulenkof68bbbc2015-02-09 12:53:18 -0800609 const void* bytes, size_t length) override {
610 data.append(reinterpret_cast<const char*>(bytes), length);
adlr@google.comc98a7ed2009-12-04 18:54:03 +0000611 }
Alex Deymo610277e2014-11-11 21:18:11 -0800612 void TransferComplete(HttpFetcher* fetcher, bool successful) override {
Andrew de los Reyesfb4ad7d2010-07-19 10:43:46 -0700613 EXPECT_TRUE(successful);
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800614 EXPECT_EQ(kHttpResponsePartialContent, fetcher->http_response_code());
Alex Deymo60ca1a72015-06-18 18:19:15 -0700615 MessageLoop::current()->BreakLoop();
adlr@google.comc98a7ed2009-12-04 18:54:03 +0000616 }
Alex Deymo610277e2014-11-11 21:18:11 -0800617 void TransferTerminated(HttpFetcher* fetcher) override {
Darin Petkov9ce452b2010-11-17 14:33:28 -0800618 ADD_FAILURE();
619 }
adlr@google.comc98a7ed2009-12-04 18:54:03 +0000620 string data;
adlr@google.comc98a7ed2009-12-04 18:54:03 +0000621};
Alex Vakulenkod2779df2014-06-16 13:19:00 -0700622} // namespace
adlr@google.comc98a7ed2009-12-04 18:54:03 +0000623
624TYPED_TEST(HttpFetcherTest, FlakyTest) {
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800625 if (this->test_.IsMock())
adlr@google.comc98a7ed2009-12-04 18:54:03 +0000626 return;
adlr@google.comc98a7ed2009-12-04 18:54:03 +0000627 {
628 FlakyHttpFetcherTestDelegate delegate;
Ben Chan02f7c1d2014-10-18 15:18:02 -0700629 unique_ptr<HttpFetcher> fetcher(this->test_.NewSmallFetcher());
adlr@google.comc98a7ed2009-12-04 18:54:03 +0000630 fetcher->set_delegate(&delegate);
631
Ben Chan02f7c1d2014-10-18 15:18:02 -0700632 unique_ptr<HttpServer> server(this->test_.CreateServer());
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800633 ASSERT_TRUE(server->started_);
adlr@google.comc98a7ed2009-12-04 18:54:03 +0000634
Alex Deymo60ca1a72015-06-18 18:19:15 -0700635 this->loop_.PostTask(FROM_HERE, base::Bind(
636 &StartTransfer,
637 fetcher.get(),
638 LocalServerUrlForPath(server->GetPort(),
639 base::StringPrintf("/flaky/%d/%d/%d/%d",
640 kBigLength,
641 kFlakyTruncateLength,
642 kFlakySleepEvery,
643 kFlakySleepSecs))));
644 this->loop_.Run();
adlr@google.comc98a7ed2009-12-04 18:54:03 +0000645
646 // verify the data we get back
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800647 ASSERT_EQ(kBigLength, delegate.data.size());
648 for (int i = 0; i < kBigLength; i += 10) {
adlr@google.comc98a7ed2009-12-04 18:54:03 +0000649 // Assert so that we don't flood the screen w/ EXPECT errors on failure.
650 ASSERT_EQ(delegate.data.substr(i, 10), "abcdefghij");
651 }
652 }
adlr@google.comc98a7ed2009-12-04 18:54:03 +0000653}
654
Andrew de los Reyes9bbd1872010-07-16 14:52:29 -0700655namespace {
Chris Sosa0a364bb2014-06-10 18:18:24 -0700656// This delegate kills the server attached to it after receiving any bytes.
657// This can be used for testing what happens when you try to fetch data and
658// the server dies.
Andrew de los Reyes9bbd1872010-07-16 14:52:29 -0700659class FailureHttpFetcherTestDelegate : public HttpFetcherDelegate {
660 public:
Alex Vakulenkod2779df2014-06-16 13:19:00 -0700661 explicit FailureHttpFetcherTestDelegate(PythonHttpServer* server)
Alex Deymo60ca1a72015-06-18 18:19:15 -0700662 : server_(server) {}
Jay Srinivasan135a58b2012-07-13 12:46:49 -0700663
Alex Deymo610277e2014-11-11 21:18:11 -0800664 ~FailureHttpFetcherTestDelegate() override {
Jay Srinivasan135a58b2012-07-13 12:46:49 -0700665 if (server_) {
666 LOG(INFO) << "Stopping server in destructor";
667 delete server_;
668 LOG(INFO) << "server stopped";
669 }
670 }
671
Alex Deymo610277e2014-11-11 21:18:11 -0800672 void ReceivedBytes(HttpFetcher* fetcher,
Alex Vakulenkof68bbbc2015-02-09 12:53:18 -0800673 const void* bytes, size_t length) override {
Andrew de los Reyes9bbd1872010-07-16 14:52:29 -0700674 if (server_) {
Jay Srinivasan135a58b2012-07-13 12:46:49 -0700675 LOG(INFO) << "Stopping server in ReceivedBytes";
Andrew de los Reyes9bbd1872010-07-16 14:52:29 -0700676 delete server_;
677 LOG(INFO) << "server stopped";
Alex Vakulenko88b591f2014-08-28 16:48:57 -0700678 server_ = nullptr;
Andrew de los Reyes9bbd1872010-07-16 14:52:29 -0700679 }
680 }
Alex Deymo610277e2014-11-11 21:18:11 -0800681 void TransferComplete(HttpFetcher* fetcher, bool successful) override {
Andrew de los Reyes9bbd1872010-07-16 14:52:29 -0700682 EXPECT_FALSE(successful);
Chris Sosa0a364bb2014-06-10 18:18:24 -0700683 EXPECT_EQ(0, fetcher->http_response_code());
Alex Deymo60ca1a72015-06-18 18:19:15 -0700684 MessageLoop::current()->BreakLoop();
Andrew de los Reyes9bbd1872010-07-16 14:52:29 -0700685 }
Alex Deymo610277e2014-11-11 21:18:11 -0800686 void TransferTerminated(HttpFetcher* fetcher) override {
Darin Petkov9ce452b2010-11-17 14:33:28 -0800687 ADD_FAILURE();
688 }
Andrew de los Reyes9bbd1872010-07-16 14:52:29 -0700689 PythonHttpServer* server_;
690};
Alex Vakulenkod2779df2014-06-16 13:19:00 -0700691} // namespace
Andrew de los Reyes9bbd1872010-07-16 14:52:29 -0700692
693
694TYPED_TEST(HttpFetcherTest, FailureTest) {
Chris Sosa0a364bb2014-06-10 18:18:24 -0700695 // This test ensures that a fetcher responds correctly when a server isn't
696 // available at all.
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800697 if (this->test_.IsMock())
Andrew de los Reyes9bbd1872010-07-16 14:52:29 -0700698 return;
Andrew de los Reyes9bbd1872010-07-16 14:52:29 -0700699 {
Alex Vakulenko88b591f2014-08-28 16:48:57 -0700700 FailureHttpFetcherTestDelegate delegate(nullptr);
Ben Chan02f7c1d2014-10-18 15:18:02 -0700701 unique_ptr<HttpFetcher> fetcher(this->test_.NewSmallFetcher());
Andrew de los Reyes9bbd1872010-07-16 14:52:29 -0700702 fetcher->set_delegate(&delegate);
703
Alex Deymo60ca1a72015-06-18 18:19:15 -0700704 this->loop_.PostTask(FROM_HERE,
705 base::Bind(StartTransfer,
706 fetcher.get(),
707 "http://host_doesnt_exist99999999"));
708 this->loop_.Run();
Andrew de los Reyes9bbd1872010-07-16 14:52:29 -0700709
710 // Exiting and testing happens in the delegate
711 }
Andrew de los Reyes9bbd1872010-07-16 14:52:29 -0700712}
713
714TYPED_TEST(HttpFetcherTest, ServerDiesTest) {
Chris Sosa0a364bb2014-06-10 18:18:24 -0700715 // This test starts a new http server and kills it after receiving its first
716 // set of bytes. It test whether or not our fetcher eventually gives up on
717 // retries and aborts correctly.
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800718 if (this->test_.IsMock())
Andrew de los Reyes9bbd1872010-07-16 14:52:29 -0700719 return;
Andrew de los Reyes9bbd1872010-07-16 14:52:29 -0700720 {
Chris Sosa0a364bb2014-06-10 18:18:24 -0700721 PythonHttpServer* server = new PythonHttpServer();
722 int port = server->GetPort();
723 ASSERT_TRUE(server->started_);
724
725 // Handles destruction and claims ownership.
726 FailureHttpFetcherTestDelegate delegate(server);
Ben Chan02f7c1d2014-10-18 15:18:02 -0700727 unique_ptr<HttpFetcher> fetcher(this->test_.NewSmallFetcher());
Andrew de los Reyes9bbd1872010-07-16 14:52:29 -0700728 fetcher->set_delegate(&delegate);
729
Alex Deymo60ca1a72015-06-18 18:19:15 -0700730 this->loop_.PostTask(FROM_HERE, base::Bind(
731 StartTransfer,
732 fetcher.get(),
733 LocalServerUrlForPath(port,
734 base::StringPrintf("/flaky/%d/%d/%d/%d",
735 kBigLength,
736 kFlakyTruncateLength,
737 kFlakySleepEvery,
738 kFlakySleepSecs))));
739 this->loop_.Run();
Andrew de los Reyes9bbd1872010-07-16 14:52:29 -0700740
741 // Exiting and testing happens in the delegate
742 }
Andrew de los Reyes9bbd1872010-07-16 14:52:29 -0700743}
744
Darin Petkov41c2fcf2010-08-25 13:14:48 -0700745namespace {
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800746const HttpResponseCode kRedirectCodes[] = {
747 kHttpResponseMovedPermanently, kHttpResponseFound, kHttpResponseSeeOther,
748 kHttpResponseTempRedirect
749};
Darin Petkov41c2fcf2010-08-25 13:14:48 -0700750
751class RedirectHttpFetcherTestDelegate : public HttpFetcherDelegate {
752 public:
Alex Vakulenkod2779df2014-06-16 13:19:00 -0700753 explicit RedirectHttpFetcherTestDelegate(bool expected_successful)
Darin Petkov41c2fcf2010-08-25 13:14:48 -0700754 : expected_successful_(expected_successful) {}
Alex Deymo610277e2014-11-11 21:18:11 -0800755 void ReceivedBytes(HttpFetcher* fetcher,
Alex Vakulenkof68bbbc2015-02-09 12:53:18 -0800756 const void* bytes, size_t length) override {
757 data.append(reinterpret_cast<const char*>(bytes), length);
Darin Petkov41c2fcf2010-08-25 13:14:48 -0700758 }
Alex Deymo610277e2014-11-11 21:18:11 -0800759 void TransferComplete(HttpFetcher* fetcher, bool successful) override {
Darin Petkov41c2fcf2010-08-25 13:14:48 -0700760 EXPECT_EQ(expected_successful_, successful);
Alex Vakulenkod2779df2014-06-16 13:19:00 -0700761 if (expected_successful_) {
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800762 EXPECT_EQ(kHttpResponseOk, fetcher->http_response_code());
Alex Vakulenkod2779df2014-06-16 13:19:00 -0700763 } else {
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800764 EXPECT_GE(fetcher->http_response_code(), kHttpResponseMovedPermanently);
765 EXPECT_LE(fetcher->http_response_code(), kHttpResponseTempRedirect);
Darin Petkovcb466212010-08-26 09:40:11 -0700766 }
Alex Deymo60ca1a72015-06-18 18:19:15 -0700767 MessageLoop::current()->BreakLoop();
Darin Petkov41c2fcf2010-08-25 13:14:48 -0700768 }
Alex Deymo610277e2014-11-11 21:18:11 -0800769 void TransferTerminated(HttpFetcher* fetcher) override {
Darin Petkov9ce452b2010-11-17 14:33:28 -0800770 ADD_FAILURE();
771 }
Darin Petkov41c2fcf2010-08-25 13:14:48 -0700772 bool expected_successful_;
773 string data;
Darin Petkov41c2fcf2010-08-25 13:14:48 -0700774};
775
776// RedirectTest takes ownership of |http_fetcher|.
Gilad Arnoldb6c562a2013-07-01 02:19:26 -0700777void RedirectTest(const HttpServer* server,
778 bool expected_successful,
Darin Petkov41c2fcf2010-08-25 13:14:48 -0700779 const string& url,
780 HttpFetcher* http_fetcher) {
Alex Deymo60ca1a72015-06-18 18:19:15 -0700781 RedirectHttpFetcherTestDelegate delegate(expected_successful);
782 unique_ptr<HttpFetcher> fetcher(http_fetcher);
783 fetcher->set_delegate(&delegate);
Darin Petkov41c2fcf2010-08-25 13:14:48 -0700784
Alex Deymo60ca1a72015-06-18 18:19:15 -0700785 MessageLoop::current()->PostTask(FROM_HERE, base::Bind(
786 StartTransfer,
787 fetcher.get(),
788 LocalServerUrlForPath(server->GetPort(), url)));
789 MessageLoop::current()->Run();
790 if (expected_successful) {
791 // verify the data we get back
792 ASSERT_EQ(kMediumLength, delegate.data.size());
793 for (int i = 0; i < kMediumLength; i += 10) {
794 // Assert so that we don't flood the screen w/ EXPECT errors on failure.
795 ASSERT_EQ(delegate.data.substr(i, 10), "abcdefghij");
Darin Petkov41c2fcf2010-08-25 13:14:48 -0700796 }
797 }
Darin Petkov41c2fcf2010-08-25 13:14:48 -0700798}
Alex Vakulenkod2779df2014-06-16 13:19:00 -0700799} // namespace
Darin Petkov41c2fcf2010-08-25 13:14:48 -0700800
801TYPED_TEST(HttpFetcherTest, SimpleRedirectTest) {
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800802 if (this->test_.IsMock())
Darin Petkov41c2fcf2010-08-25 13:14:48 -0700803 return;
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800804
Ben Chan02f7c1d2014-10-18 15:18:02 -0700805 unique_ptr<HttpServer> server(this->test_.CreateServer());
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800806 ASSERT_TRUE(server->started_);
807
Darin Petkov41c2fcf2010-08-25 13:14:48 -0700808 for (size_t c = 0; c < arraysize(kRedirectCodes); ++c) {
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800809 const string url = base::StringPrintf("/redirect/%d/download/%d",
810 kRedirectCodes[c],
811 kMediumLength);
Gilad Arnoldb6c562a2013-07-01 02:19:26 -0700812 RedirectTest(server.get(), true, url, this->test_.NewLargeFetcher());
Darin Petkov41c2fcf2010-08-25 13:14:48 -0700813 }
814}
815
816TYPED_TEST(HttpFetcherTest, MaxRedirectTest) {
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800817 if (this->test_.IsMock())
Darin Petkov41c2fcf2010-08-25 13:14:48 -0700818 return;
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800819
Ben Chan02f7c1d2014-10-18 15:18:02 -0700820 unique_ptr<HttpServer> server(this->test_.CreateServer());
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800821 ASSERT_TRUE(server->started_);
822
Darin Petkov41c2fcf2010-08-25 13:14:48 -0700823 string url;
David Zeuthen34135a92013-08-06 11:16:16 -0700824 for (int r = 0; r < kDownloadMaxRedirects; r++) {
Darin Petkov41c2fcf2010-08-25 13:14:48 -0700825 url += base::StringPrintf("/redirect/%d",
826 kRedirectCodes[r % arraysize(kRedirectCodes)]);
827 }
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800828 url += base::StringPrintf("/download/%d", kMediumLength);
Gilad Arnoldb6c562a2013-07-01 02:19:26 -0700829 RedirectTest(server.get(), true, url, this->test_.NewLargeFetcher());
Darin Petkov41c2fcf2010-08-25 13:14:48 -0700830}
831
832TYPED_TEST(HttpFetcherTest, BeyondMaxRedirectTest) {
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800833 if (this->test_.IsMock())
Darin Petkov41c2fcf2010-08-25 13:14:48 -0700834 return;
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800835
Ben Chan02f7c1d2014-10-18 15:18:02 -0700836 unique_ptr<HttpServer> server(this->test_.CreateServer());
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800837 ASSERT_TRUE(server->started_);
838
Darin Petkov41c2fcf2010-08-25 13:14:48 -0700839 string url;
David Zeuthen34135a92013-08-06 11:16:16 -0700840 for (int r = 0; r < kDownloadMaxRedirects + 1; r++) {
Darin Petkov41c2fcf2010-08-25 13:14:48 -0700841 url += base::StringPrintf("/redirect/%d",
842 kRedirectCodes[r % arraysize(kRedirectCodes)]);
843 }
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800844 url += base::StringPrintf("/download/%d", kMediumLength);
Gilad Arnoldb6c562a2013-07-01 02:19:26 -0700845 RedirectTest(server.get(), false, url, this->test_.NewLargeFetcher());
Darin Petkov41c2fcf2010-08-25 13:14:48 -0700846}
847
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -0700848namespace {
849class MultiHttpFetcherTestDelegate : public HttpFetcherDelegate {
850 public:
Alex Vakulenkod2779df2014-06-16 13:19:00 -0700851 explicit MultiHttpFetcherTestDelegate(int expected_response_code)
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -0700852 : expected_response_code_(expected_response_code) {}
Gilad Arnolde4ad2502011-12-29 17:08:54 -0800853
Alex Deymo610277e2014-11-11 21:18:11 -0800854 void ReceivedBytes(HttpFetcher* fetcher,
Alex Vakulenkof68bbbc2015-02-09 12:53:18 -0800855 const void* bytes, size_t length) override {
Darin Petkov9ce452b2010-11-17 14:33:28 -0800856 EXPECT_EQ(fetcher, fetcher_.get());
Alex Vakulenkof68bbbc2015-02-09 12:53:18 -0800857 data.append(reinterpret_cast<const char*>(bytes), length);
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -0700858 }
Gilad Arnolde4ad2502011-12-29 17:08:54 -0800859
Alex Deymo610277e2014-11-11 21:18:11 -0800860 void TransferComplete(HttpFetcher* fetcher, bool successful) override {
Darin Petkov9ce452b2010-11-17 14:33:28 -0800861 EXPECT_EQ(fetcher, fetcher_.get());
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800862 EXPECT_EQ(expected_response_code_ != kHttpResponseUndefined, successful);
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -0700863 if (expected_response_code_ != 0)
864 EXPECT_EQ(expected_response_code_, fetcher->http_response_code());
Darin Petkov9ce452b2010-11-17 14:33:28 -0800865 // Destroy the fetcher (because we're allowed to).
Alex Vakulenko88b591f2014-08-28 16:48:57 -0700866 fetcher_.reset(nullptr);
Alex Deymo60ca1a72015-06-18 18:19:15 -0700867 MessageLoop::current()->BreakLoop();
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -0700868 }
Gilad Arnolde4ad2502011-12-29 17:08:54 -0800869
Alex Deymo610277e2014-11-11 21:18:11 -0800870 void TransferTerminated(HttpFetcher* fetcher) override {
Darin Petkov9ce452b2010-11-17 14:33:28 -0800871 ADD_FAILURE();
872 }
Gilad Arnolde4ad2502011-12-29 17:08:54 -0800873
Ben Chan02f7c1d2014-10-18 15:18:02 -0700874 unique_ptr<HttpFetcher> fetcher_;
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -0700875 int expected_response_code_;
876 string data;
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -0700877};
878
879void MultiTest(HttpFetcher* fetcher_in,
880 const string& url,
Ben Chanf9cb98c2014-09-21 18:31:30 -0700881 const vector<pair<off_t, off_t>>& ranges,
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -0700882 const string& expected_prefix,
883 off_t expected_size,
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800884 HttpResponseCode expected_response_code) {
Alex Deymo60ca1a72015-06-18 18:19:15 -0700885 MultiHttpFetcherTestDelegate delegate(expected_response_code);
886 delegate.fetcher_.reset(fetcher_in);
Jay Srinivasan43488792012-06-19 00:25:31 -0700887
Alex Deymo60ca1a72015-06-18 18:19:15 -0700888 MultiRangeHttpFetcher* multi_fetcher =
889 dynamic_cast<MultiRangeHttpFetcher*>(fetcher_in);
890 ASSERT_TRUE(multi_fetcher);
891 multi_fetcher->ClearRanges();
892 for (vector<pair<off_t, off_t>>::const_iterator it = ranges.begin(),
893 e = ranges.end(); it != e; ++it) {
894 string tmp_str = base::StringPrintf("%jd+", it->first);
895 if (it->second > 0) {
896 base::StringAppendF(&tmp_str, "%jd", it->second);
897 multi_fetcher->AddRange(it->first, it->second);
898 } else {
899 base::StringAppendF(&tmp_str, "?");
900 multi_fetcher->AddRange(it->first);
Andrew de los Reyes819fef22010-12-17 11:33:58 -0800901 }
Alex Deymo60ca1a72015-06-18 18:19:15 -0700902 LOG(INFO) << "added range: " << tmp_str;
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -0700903 }
Alex Deymo60ca1a72015-06-18 18:19:15 -0700904 dynamic_cast<FakeSystemState*>(fetcher_in->GetSystemState())
905 ->fake_hardware()->SetIsOfficialBuild(false);
906 multi_fetcher->set_delegate(&delegate);
907
908 MessageLoop::current()->PostTask(
909 FROM_HERE,
910 base::Bind(StartTransfer, multi_fetcher, url));
911 MessageLoop::current()->Run();
912
913 EXPECT_EQ(expected_size, delegate.data.size());
914 EXPECT_EQ(expected_prefix,
915 string(delegate.data.data(), expected_prefix.size()));
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -0700916}
Alex Vakulenkod2779df2014-06-16 13:19:00 -0700917} // namespace
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -0700918
Darin Petkov9ce452b2010-11-17 14:33:28 -0800919TYPED_TEST(HttpFetcherTest, MultiHttpFetcherSimpleTest) {
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800920 if (!this->test_.IsMulti())
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -0700921 return;
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800922
Ben Chan02f7c1d2014-10-18 15:18:02 -0700923 unique_ptr<HttpServer> server(this->test_.CreateServer());
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800924 ASSERT_TRUE(server->started_);
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -0700925
Ben Chanf9cb98c2014-09-21 18:31:30 -0700926 vector<pair<off_t, off_t>> ranges;
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -0700927 ranges.push_back(make_pair(0, 25));
Gilad Arnolde4ad2502011-12-29 17:08:54 -0800928 ranges.push_back(make_pair(99, 0));
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800929 MultiTest(this->test_.NewLargeFetcher(),
Gilad Arnoldb6c562a2013-07-01 02:19:26 -0700930 this->test_.BigUrl(server->GetPort()),
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -0700931 ranges,
932 "abcdefghijabcdefghijabcdejabcdefghijabcdef",
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800933 kBigLength - (99 - 25),
934 kHttpResponsePartialContent);
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -0700935}
936
937TYPED_TEST(HttpFetcherTest, MultiHttpFetcherLengthLimitTest) {
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800938 if (!this->test_.IsMulti())
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -0700939 return;
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800940
Ben Chan02f7c1d2014-10-18 15:18:02 -0700941 unique_ptr<HttpServer> server(this->test_.CreateServer());
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800942 ASSERT_TRUE(server->started_);
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -0700943
Ben Chanf9cb98c2014-09-21 18:31:30 -0700944 vector<pair<off_t, off_t>> ranges;
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -0700945 ranges.push_back(make_pair(0, 24));
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800946 MultiTest(this->test_.NewLargeFetcher(),
Gilad Arnoldb6c562a2013-07-01 02:19:26 -0700947 this->test_.BigUrl(server->GetPort()),
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -0700948 ranges,
949 "abcdefghijabcdefghijabcd",
950 24,
Gilad Arnolde4ad2502011-12-29 17:08:54 -0800951 kHttpResponsePartialContent);
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -0700952}
953
954TYPED_TEST(HttpFetcherTest, MultiHttpFetcherMultiEndTest) {
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800955 if (!this->test_.IsMulti())
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -0700956 return;
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800957
Ben Chan02f7c1d2014-10-18 15:18:02 -0700958 unique_ptr<HttpServer> server(this->test_.CreateServer());
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800959 ASSERT_TRUE(server->started_);
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -0700960
Ben Chanf9cb98c2014-09-21 18:31:30 -0700961 vector<pair<off_t, off_t>> ranges;
Gilad Arnolde4ad2502011-12-29 17:08:54 -0800962 ranges.push_back(make_pair(kBigLength - 2, 0));
963 ranges.push_back(make_pair(kBigLength - 3, 0));
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800964 MultiTest(this->test_.NewLargeFetcher(),
Gilad Arnoldb6c562a2013-07-01 02:19:26 -0700965 this->test_.BigUrl(server->GetPort()),
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -0700966 ranges,
967 "ijhij",
968 5,
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800969 kHttpResponsePartialContent);
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -0700970}
971
972TYPED_TEST(HttpFetcherTest, MultiHttpFetcherInsufficientTest) {
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800973 if (!this->test_.IsMulti())
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -0700974 return;
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800975
Ben Chan02f7c1d2014-10-18 15:18:02 -0700976 unique_ptr<HttpServer> server(this->test_.CreateServer());
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800977 ASSERT_TRUE(server->started_);
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -0700978
Ben Chanf9cb98c2014-09-21 18:31:30 -0700979 vector<pair<off_t, off_t>> ranges;
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800980 ranges.push_back(make_pair(kBigLength - 2, 4));
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -0700981 for (int i = 0; i < 2; ++i) {
Andrew de los Reyes819fef22010-12-17 11:33:58 -0800982 LOG(INFO) << "i = " << i;
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800983 MultiTest(this->test_.NewLargeFetcher(),
Gilad Arnoldb6c562a2013-07-01 02:19:26 -0700984 this->test_.BigUrl(server->GetPort()),
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -0700985 ranges,
986 "ij",
987 2,
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800988 kHttpResponseUndefined);
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -0700989 ranges.push_back(make_pair(0, 5));
990 }
991}
992
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800993// Issue #18143: when a fetch of a secondary chunk out of a chain, then it
994// should retry with other proxies listed before giving up.
995//
996// (1) successful recovery: The offset fetch will fail twice but succeed with
997// the third proxy.
998TYPED_TEST(HttpFetcherTest, MultiHttpFetcherErrorIfOffsetRecoverableTest) {
999 if (!this->test_.IsMulti())
1000 return;
1001
Ben Chan02f7c1d2014-10-18 15:18:02 -07001002 unique_ptr<HttpServer> server(this->test_.CreateServer());
Gilad Arnold9bedeb52011-11-17 16:19:57 -08001003 ASSERT_TRUE(server->started_);
1004
Ben Chanf9cb98c2014-09-21 18:31:30 -07001005 vector<pair<off_t, off_t>> ranges;
Gilad Arnold9bedeb52011-11-17 16:19:57 -08001006 ranges.push_back(make_pair(0, 25));
Gilad Arnolde4ad2502011-12-29 17:08:54 -08001007 ranges.push_back(make_pair(99, 0));
Gilad Arnold9bedeb52011-11-17 16:19:57 -08001008 MultiTest(this->test_.NewLargeFetcher(3),
Gilad Arnoldb6c562a2013-07-01 02:19:26 -07001009 LocalServerUrlForPath(server->GetPort(),
1010 base::StringPrintf("/error-if-offset/%d/2",
Gilad Arnold9bedeb52011-11-17 16:19:57 -08001011 kBigLength)),
1012 ranges,
1013 "abcdefghijabcdefghijabcdejabcdefghijabcdef",
1014 kBigLength - (99 - 25),
1015 kHttpResponsePartialContent);
1016}
1017
1018// (2) unsuccessful recovery: The offset fetch will fail repeatedly. The
1019// fetcher will signal a (failed) completed transfer to the delegate.
1020TYPED_TEST(HttpFetcherTest, MultiHttpFetcherErrorIfOffsetUnrecoverableTest) {
1021 if (!this->test_.IsMulti())
1022 return;
1023
Ben Chan02f7c1d2014-10-18 15:18:02 -07001024 unique_ptr<HttpServer> server(this->test_.CreateServer());
Gilad Arnold9bedeb52011-11-17 16:19:57 -08001025 ASSERT_TRUE(server->started_);
1026
Ben Chanf9cb98c2014-09-21 18:31:30 -07001027 vector<pair<off_t, off_t>> ranges;
Gilad Arnold9bedeb52011-11-17 16:19:57 -08001028 ranges.push_back(make_pair(0, 25));
Gilad Arnolde4ad2502011-12-29 17:08:54 -08001029 ranges.push_back(make_pair(99, 0));
Gilad Arnold9bedeb52011-11-17 16:19:57 -08001030 MultiTest(this->test_.NewLargeFetcher(2),
Gilad Arnoldb6c562a2013-07-01 02:19:26 -07001031 LocalServerUrlForPath(server->GetPort(),
1032 base::StringPrintf("/error-if-offset/%d/3",
Gilad Arnold9bedeb52011-11-17 16:19:57 -08001033 kBigLength)),
1034 ranges,
1035 "abcdefghijabcdefghijabcde", // only received the first chunk
1036 25,
1037 kHttpResponseUndefined);
1038}
1039
1040
1041
Andrew de los Reyesd57d1472010-10-21 13:34:08 -07001042namespace {
Darin Petkovfc7a0ce2010-10-25 10:38:37 -07001043class BlockedTransferTestDelegate : public HttpFetcherDelegate {
Andrew de los Reyesd57d1472010-10-21 13:34:08 -07001044 public:
Alex Deymo610277e2014-11-11 21:18:11 -08001045 void ReceivedBytes(HttpFetcher* fetcher,
Alex Vakulenkof68bbbc2015-02-09 12:53:18 -08001046 const void* bytes, size_t length) override {
Andrew de los Reyesd57d1472010-10-21 13:34:08 -07001047 ADD_FAILURE();
1048 }
Alex Deymo610277e2014-11-11 21:18:11 -08001049 void TransferComplete(HttpFetcher* fetcher, bool successful) override {
Andrew de los Reyesd57d1472010-10-21 13:34:08 -07001050 EXPECT_FALSE(successful);
Alex Deymo60ca1a72015-06-18 18:19:15 -07001051 MessageLoop::current()->BreakLoop();
Andrew de los Reyesd57d1472010-10-21 13:34:08 -07001052 }
Alex Deymo610277e2014-11-11 21:18:11 -08001053 void TransferTerminated(HttpFetcher* fetcher) override {
Darin Petkov9ce452b2010-11-17 14:33:28 -08001054 ADD_FAILURE();
1055 }
Andrew de los Reyesd57d1472010-10-21 13:34:08 -07001056};
1057
Alex Deymo60ca1a72015-06-18 18:19:15 -07001058void BlockedTransferTestHelper(AnyHttpFetcherTest* fetcher_test,
1059 bool is_official_build) {
1060 if (fetcher_test->IsMock() || fetcher_test->IsMulti())
1061 return;
1062
1063 unique_ptr<HttpServer> server(fetcher_test->CreateServer());
1064 ASSERT_TRUE(server->started_);
1065
1066 BlockedTransferTestDelegate delegate;
1067 unique_ptr<HttpFetcher> fetcher(fetcher_test->NewLargeFetcher());
1068 LOG(INFO) << "is_official_build: " << is_official_build;
1069 // NewLargeFetcher creates the HttpFetcher* with a FakeSystemState.
1070 dynamic_cast<FakeSystemState*>(fetcher->GetSystemState())
1071 ->fake_hardware()->SetIsOfficialBuild(is_official_build);
1072 fetcher->set_delegate(&delegate);
1073
1074 MessageLoop::current()->PostTask(FROM_HERE, base::Bind(
1075 StartTransfer,
1076 fetcher.get(),
1077 LocalServerUrlForPath(server->GetPort(),
1078 fetcher_test->SmallUrl(server->GetPort()))));
1079 MessageLoop::current()->Run();
1080}
Andrew de los Reyesd57d1472010-10-21 13:34:08 -07001081} // namespace
1082
Darin Petkovfc7a0ce2010-10-25 10:38:37 -07001083TYPED_TEST(HttpFetcherTest, BlockedTransferTest) {
Alex Deymo60ca1a72015-06-18 18:19:15 -07001084 BlockedTransferTestHelper(&this->test_, false);
1085}
Andrew de los Reyesd57d1472010-10-21 13:34:08 -07001086
Alex Deymo60ca1a72015-06-18 18:19:15 -07001087TYPED_TEST(HttpFetcherTest, BlockedTransferOfficialBuildTest) {
1088 BlockedTransferTestHelper(&this->test_, true);
Andrew de los Reyesd57d1472010-10-21 13:34:08 -07001089}
1090
rspangler@google.com49fdf182009-10-10 00:57:34 +00001091} // namespace chromeos_update_engine