1aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo//
2aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// Copyright (C) 2012 The Android Open Source Project
3aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo//
4aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// Licensed under the Apache License, Version 2.0 (the "License");
5aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// you may not use this file except in compliance with the License.
6aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// You may obtain a copy of the License at
7aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo//
8aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo//      http://www.apache.org/licenses/LICENSE-2.0
9aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo//
10aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// Unless required by applicable law or agreed to in writing, software
11aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// distributed under the License is distributed on an "AS IS" BASIS,
12aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// See the License for the specific language governing permissions and
14aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// limitations under the License.
15aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo//
1649fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com
17b6c562adec6e9491712f156f8fd50e2b807ff302Gilad Arnold#include <netinet/in.h>
18b6c562adec6e9491712f156f8fd50e2b807ff302Gilad Arnold#include <netinet/ip.h>
19b6c562adec6e9491712f156f8fd50e2b807ff302Gilad Arnold#include <sys/socket.h>
2049fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com#include <unistd.h>
2141c2fcf4525a3b4e8960c4b71dfe4f4f11c8224fDarin Petkov
2202f7c1dee242f490143791dbb73fa23fa3007cfaBen Chan#include <memory>
23c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com#include <string>
243fd5d30433509859bfdcc0b650e242981410c6a7Andrew de los Reyes#include <utility>
25c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com#include <vector>
2641c2fcf4525a3b4e8960c4b71dfe4f4f11c8224fDarin Petkov
27706a5abae125b8f5ba58a9b7e1e51570bbaa2089Alex Deymo#include <base/bind.h>
2860ca1a7bca7cc804ec80b510483081ef894de4cdAlex Deymo#include <base/location.h>
294516810fe41a39c0c55d2095679898787259ae38Andrew de los Reyes#include <base/logging.h>
30535f3b738b0bcbca23a6e361c84bf84145d6a3e6Alex Deymo#include <base/message_loop/message_loop.h>
31535f3b738b0bcbca23a6e361c84bf84145d6a3e6Alex Deymo#include <base/strings/string_number_conversions.h>
3275039d7397f03dff77bdf4e26398049ff88edc4cAlex Vakulenko#include <base/strings/string_util.h>
3375039d7397f03dff77bdf4e26398049ff88edc4cAlex Vakulenko#include <base/strings/stringprintf.h>
3475039d7397f03dff77bdf4e26398049ff88edc4cAlex Vakulenko#include <base/time/time.h>
35706a5abae125b8f5ba58a9b7e1e51570bbaa2089Alex Deymo#include <brillo/bind_lambda.h>
363f39d5cc753905874d8d93bef94f857b8808f19eAlex Vakulenko#include <brillo/message_loops/base_message_loop.h>
373f39d5cc753905874d8d93bef94f857b8808f19eAlex Vakulenko#include <brillo/message_loops/message_loop.h>
383f39d5cc753905874d8d93bef94f857b8808f19eAlex Vakulenko#include <brillo/message_loops/message_loop_utils.h>
393f39d5cc753905874d8d93bef94f857b8808f19eAlex Vakulenko#include <brillo/process.h>
403f39d5cc753905874d8d93bef94f857b8808f19eAlex Vakulenko#include <brillo/streams/file_stream.h>
413f39d5cc753905874d8d93bef94f857b8808f19eAlex Vakulenko#include <brillo/streams/stream.h>
424516810fe41a39c0c55d2095679898787259ae38Andrew de los Reyes#include <gtest/gtest.h>
434516810fe41a39c0c55d2095679898787259ae38Andrew de los Reyes
44c1c17b4ed6a3896b6343e737fd89682fa0c8436bAlex Deymo#include "update_engine/common/fake_hardware.h"
456e3ffe73d27de744ef494292c003b5ba907799dfAlex Deymo#include "update_engine/common/file_fetcher.h"
4639910dcd1d68987ccee7c3031dc269233a8490bbAlex Deymo#include "update_engine/common/http_common.h"
4739910dcd1d68987ccee7c3031dc269233a8490bbAlex Deymo#include "update_engine/common/mock_http_fetcher.h"
4839910dcd1d68987ccee7c3031dc269233a8490bbAlex Deymo#include "update_engine/common/multi_range_http_fetcher.h"
4939910dcd1d68987ccee7c3031dc269233a8490bbAlex Deymo#include "update_engine/common/test_utils.h"
5039910dcd1d68987ccee7c3031dc269233a8490bbAlex Deymo#include "update_engine/common/utils.h"
518b01f44bf61c5cceb83b2ff4f2c0070a9ab946d7Alex Deymo#include "update_engine/libcurl_http_fetcher.h"
52f28585764e91b7c25a7c2856ff645c8bb22d64a9Alex Deymo#include "update_engine/mock_proxy_resolver.h"
534516810fe41a39c0c55d2095679898787259ae38Andrew de los Reyes#include "update_engine/proxy_resolver.h"
5449fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com
553f39d5cc753905874d8d93bef94f857b8808f19eAlex Vakulenkousing brillo::MessageLoop;
563fd5d30433509859bfdcc0b650e242981410c6a7Andrew de los Reyesusing std::make_pair;
57819fef2e0fa08984cf31e848e704442c500ea4f9Andrew de los Reyesusing std::pair;
58c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.comusing std::string;
5902f7c1dee242f490143791dbb73fa23fa3007cfaBen Chanusing std::unique_ptr;
60c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.comusing std::vector;
61f28585764e91b7c25a7c2856ff645c8bb22d64a9Alex Deymousing testing::DoAll;
62f28585764e91b7c25a7c2856ff645c8bb22d64a9Alex Deymousing testing::Return;
63f28585764e91b7c25a7c2856ff645c8bb22d64a9Alex Deymousing testing::SaveArg;
64f28585764e91b7c25a7c2856ff645c8bb22d64a9Alex Deymousing testing::_;
65c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com
669bedeb51f80c9547269eef6c2ec09596033bb818Gilad Arnoldnamespace {
679bedeb51f80c9547269eef6c2ec09596033bb818Gilad Arnold
689bedeb51f80c9547269eef6c2ec09596033bb818Gilad Arnoldconst int kBigLength           = 100000;
699bedeb51f80c9547269eef6c2ec09596033bb818Gilad Arnoldconst int kMediumLength        = 1000;
7034bf1ee4ff22ece3dfc5c207e7e1f46aaff73a24Gilad Arnoldconst int kFlakyTruncateLength = 29000;
7134bf1ee4ff22ece3dfc5c207e7e1f46aaff73a24Gilad Arnoldconst int kFlakySleepEvery     = 3;
729bedeb51f80c9547269eef6c2ec09596033bb818Gilad Arnoldconst int kFlakySleepSecs      = 10;
739bedeb51f80c9547269eef6c2ec09596033bb818Gilad Arnold
749bedeb51f80c9547269eef6c2ec09596033bb818Gilad Arnold}  // namespace
759bedeb51f80c9547269eef6c2ec09596033bb818Gilad Arnold
7649fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.comnamespace chromeos_update_engine {
7749fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com
789bedeb51f80c9547269eef6c2ec09596033bb818Gilad Arnoldstatic const char *kUnusedUrl = "unused://unused";
799bedeb51f80c9547269eef6c2ec09596033bb818Gilad Arnold
80b6c562adec6e9491712f156f8fd50e2b807ff302Gilad Arnoldstatic inline string LocalServerUrlForPath(in_port_t port,
81b6c562adec6e9491712f156f8fd50e2b807ff302Gilad Arnold                                           const string& path) {
8275039d7397f03dff77bdf4e26398049ff88edc4cAlex Vakulenko  string port_str = (port ? base::StringPrintf(":%hu", port) : "");
83b6c562adec6e9491712f156f8fd50e2b807ff302Gilad Arnold  return base::StringPrintf("http://127.0.0.1%s%s", port_str.c_str(),
84b6c562adec6e9491712f156f8fd50e2b807ff302Gilad Arnold                            path.c_str());
8549fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com}
8649fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com
879bedeb51f80c9547269eef6c2ec09596033bb818Gilad Arnold//
889bedeb51f80c9547269eef6c2ec09596033bb818Gilad Arnold// Class hierarchy for HTTP server implementations.
899bedeb51f80c9547269eef6c2ec09596033bb818Gilad Arnold//
909bedeb51f80c9547269eef6c2ec09596033bb818Gilad Arnold
919bedeb51f80c9547269eef6c2ec09596033bb818Gilad Arnoldclass HttpServer {
9249fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com public:
939bedeb51f80c9547269eef6c2ec09596033bb818Gilad Arnold  // This makes it an abstract class (dirty but works).
949bedeb51f80c9547269eef6c2ec09596033bb818Gilad Arnold  virtual ~HttpServer() = 0;
959bedeb51f80c9547269eef6c2ec09596033bb818Gilad Arnold
96b6c562adec6e9491712f156f8fd50e2b807ff302Gilad Arnold  virtual in_port_t GetPort() const {
97b6c562adec6e9491712f156f8fd50e2b807ff302Gilad Arnold    return 0;
98b6c562adec6e9491712f156f8fd50e2b807ff302Gilad Arnold  }
99b6c562adec6e9491712f156f8fd50e2b807ff302Gilad Arnold
10049fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com  bool started_;
10149fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com};
10249fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com
1039bedeb51f80c9547269eef6c2ec09596033bb818Gilad ArnoldHttpServer::~HttpServer() {}
1049bedeb51f80c9547269eef6c2ec09596033bb818Gilad Arnold
10549fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com
1069bedeb51f80c9547269eef6c2ec09596033bb818Gilad Arnoldclass NullHttpServer : public HttpServer {
10749fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com public:
1089bedeb51f80c9547269eef6c2ec09596033bb818Gilad Arnold  NullHttpServer() {
1099bedeb51f80c9547269eef6c2ec09596033bb818Gilad Arnold    started_ = true;
11048085ba58516e94f045d3ab7e26c8f36e6a6936fGilad Arnold  }
11149fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com};
11249fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com
1139bedeb51f80c9547269eef6c2ec09596033bb818Gilad Arnold
1149bedeb51f80c9547269eef6c2ec09596033bb818Gilad Arnoldclass PythonHttpServer : public HttpServer {
11549fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com public:
116535f3b738b0bcbca23a6e361c84bf84145d6a3e6Alex Deymo  PythonHttpServer() : port_(0) {
11749fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com    started_ = false;
118b6c562adec6e9491712f156f8fd50e2b807ff302Gilad Arnold
119b6c562adec6e9491712f156f8fd50e2b807ff302Gilad Arnold    // Spawn the server process.
1203f39d5cc753905874d8d93bef94f857b8808f19eAlex Vakulenko    unique_ptr<brillo::Process> http_server(new brillo::ProcessImpl());
121535f3b738b0bcbca23a6e361c84bf84145d6a3e6Alex Deymo    base::FilePath test_server_path =
122535f3b738b0bcbca23a6e361c84bf84145d6a3e6Alex Deymo        test_utils::GetBuildArtifactsPath().Append("test_http_server");
123535f3b738b0bcbca23a6e361c84bf84145d6a3e6Alex Deymo    http_server->AddArg(test_server_path.value());
124535f3b738b0bcbca23a6e361c84bf84145d6a3e6Alex Deymo    http_server->RedirectUsingPipe(STDOUT_FILENO, false);
125535f3b738b0bcbca23a6e361c84bf84145d6a3e6Alex Deymo
126535f3b738b0bcbca23a6e361c84bf84145d6a3e6Alex Deymo    if (!http_server->Start()) {
127535f3b738b0bcbca23a6e361c84bf84145d6a3e6Alex Deymo      ADD_FAILURE() << "failed to spawn http server process";
12849fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com      return;
12949fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com    }
130535f3b738b0bcbca23a6e361c84bf84145d6a3e6Alex Deymo    LOG(INFO) << "started http server with pid " << http_server->pid();
131135a58b2cc8bd94c384625d375f0bf26252d6f07Jay Srinivasan
132b6c562adec6e9491712f156f8fd50e2b807ff302Gilad Arnold    // Wait for server to begin accepting connections, obtain its port.
1333f39d5cc753905874d8d93bef94f857b8808f19eAlex Vakulenko    brillo::StreamPtr stdout = brillo::FileStream::FromFileDescriptor(
134535f3b738b0bcbca23a6e361c84bf84145d6a3e6Alex Deymo        http_server->GetPipe(STDOUT_FILENO), false /* own */, nullptr);
135535f3b738b0bcbca23a6e361c84bf84145d6a3e6Alex Deymo    if (!stdout)
136535f3b738b0bcbca23a6e361c84bf84145d6a3e6Alex Deymo      return;
137535f3b738b0bcbca23a6e361c84bf84145d6a3e6Alex Deymo
138535f3b738b0bcbca23a6e361c84bf84145d6a3e6Alex Deymo    vector<char> buf(128);
139535f3b738b0bcbca23a6e361c84bf84145d6a3e6Alex Deymo    string line;
140535f3b738b0bcbca23a6e361c84bf84145d6a3e6Alex Deymo    while (line.find('\n') == string::npos) {
141535f3b738b0bcbca23a6e361c84bf84145d6a3e6Alex Deymo      size_t read;
142535f3b738b0bcbca23a6e361c84bf84145d6a3e6Alex Deymo      if (!stdout->ReadBlocking(buf.data(), buf.size(), &read, nullptr)) {
143535f3b738b0bcbca23a6e361c84bf84145d6a3e6Alex Deymo        ADD_FAILURE() << "error reading http server stdout";
144535f3b738b0bcbca23a6e361c84bf84145d6a3e6Alex Deymo        return;
145b6c562adec6e9491712f156f8fd50e2b807ff302Gilad Arnold      }
146535f3b738b0bcbca23a6e361c84bf84145d6a3e6Alex Deymo      line.append(buf.data(), read);
147535f3b738b0bcbca23a6e361c84bf84145d6a3e6Alex Deymo      if (read == 0)
148535f3b738b0bcbca23a6e361c84bf84145d6a3e6Alex Deymo        break;
149535f3b738b0bcbca23a6e361c84bf84145d6a3e6Alex Deymo    }
150535f3b738b0bcbca23a6e361c84bf84145d6a3e6Alex Deymo    // Parse the port from the output line.
151535f3b738b0bcbca23a6e361c84bf84145d6a3e6Alex Deymo    const size_t listening_msg_prefix_len = strlen(kServerListeningMsgPrefix);
152535f3b738b0bcbca23a6e361c84bf84145d6a3e6Alex Deymo    if (line.size() < listening_msg_prefix_len) {
153535f3b738b0bcbca23a6e361c84bf84145d6a3e6Alex Deymo      ADD_FAILURE() << "server output too short";
154b6c562adec6e9491712f156f8fd50e2b807ff302Gilad Arnold      return;
15549fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com    }
156135a58b2cc8bd94c384625d375f0bf26252d6f07Jay Srinivasan
157535f3b738b0bcbca23a6e361c84bf84145d6a3e6Alex Deymo    EXPECT_EQ(kServerListeningMsgPrefix,
158535f3b738b0bcbca23a6e361c84bf84145d6a3e6Alex Deymo              line.substr(0, listening_msg_prefix_len));
159535f3b738b0bcbca23a6e361c84bf84145d6a3e6Alex Deymo    string port_str = line.substr(listening_msg_prefix_len);
160535f3b738b0bcbca23a6e361c84bf84145d6a3e6Alex Deymo    port_str.resize(port_str.find('\n'));
161535f3b738b0bcbca23a6e361c84bf84145d6a3e6Alex Deymo    EXPECT_TRUE(base::StringToUint(port_str, &port_));
162535f3b738b0bcbca23a6e361c84bf84145d6a3e6Alex Deymo
163b6c562adec6e9491712f156f8fd50e2b807ff302Gilad Arnold    started_ = true;
164b6c562adec6e9491712f156f8fd50e2b807ff302Gilad Arnold    LOG(INFO) << "server running, listening on port " << port_;
165535f3b738b0bcbca23a6e361c84bf84145d6a3e6Alex Deymo
166535f3b738b0bcbca23a6e361c84bf84145d6a3e6Alex Deymo    // Any failure before this point will SIGKILL the test server if started
167535f3b738b0bcbca23a6e361c84bf84145d6a3e6Alex Deymo    // when the |http_server| goes out of scope.
168535f3b738b0bcbca23a6e361c84bf84145d6a3e6Alex Deymo    http_server_ = std::move(http_server);
16949fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com  }
1709bedeb51f80c9547269eef6c2ec09596033bb818Gilad Arnold
17149fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com  ~PythonHttpServer() {
172b6c562adec6e9491712f156f8fd50e2b807ff302Gilad Arnold    // If there's no process, do nothing.
173535f3b738b0bcbca23a6e361c84bf84145d6a3e6Alex Deymo    if (!http_server_)
17449fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com      return;
175535f3b738b0bcbca23a6e361c84bf84145d6a3e6Alex Deymo    // Wait up to 10 seconds for the process to finish. Destroying the process
176535f3b738b0bcbca23a6e361c84bf84145d6a3e6Alex Deymo    // will kill it with a SIGKILL otherwise.
177535f3b738b0bcbca23a6e361c84bf84145d6a3e6Alex Deymo    http_server_->Kill(SIGTERM, 10);
178b6c562adec6e9491712f156f8fd50e2b807ff302Gilad Arnold  }
179b6c562adec6e9491712f156f8fd50e2b807ff302Gilad Arnold
180610277efc6f7e5239158dfa4bb3b1021804326e0Alex Deymo  in_port_t GetPort() const override {
181b6c562adec6e9491712f156f8fd50e2b807ff302Gilad Arnold    return port_;
182b6c562adec6e9491712f156f8fd50e2b807ff302Gilad Arnold  }
183b6c562adec6e9491712f156f8fd50e2b807ff302Gilad Arnold
184b6c562adec6e9491712f156f8fd50e2b807ff302Gilad Arnold private:
185b6c562adec6e9491712f156f8fd50e2b807ff302Gilad Arnold  static const char* kServerListeningMsgPrefix;
186b6c562adec6e9491712f156f8fd50e2b807ff302Gilad Arnold
1873f39d5cc753905874d8d93bef94f857b8808f19eAlex Vakulenko  unique_ptr<brillo::Process> http_server_;
188535f3b738b0bcbca23a6e361c84bf84145d6a3e6Alex Deymo  unsigned int port_;
18949fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com};
19049fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com
191b6c562adec6e9491712f156f8fd50e2b807ff302Gilad Arnoldconst char* PythonHttpServer::kServerListeningMsgPrefix = "listening on port ";
192b6c562adec6e9491712f156f8fd50e2b807ff302Gilad Arnold
1939bedeb51f80c9547269eef6c2ec09596033bb818Gilad Arnold//
1949bedeb51f80c9547269eef6c2ec09596033bb818Gilad Arnold// Class hierarchy for HTTP fetcher test wrappers.
1959bedeb51f80c9547269eef6c2ec09596033bb818Gilad Arnold//
1969bedeb51f80c9547269eef6c2ec09596033bb818Gilad Arnold
1979bedeb51f80c9547269eef6c2ec09596033bb818Gilad Arnoldclass AnyHttpFetcherTest {
19849fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com public:
19977f79e876a77796fc248d099b6574f05bd23c954Chris Sosa  AnyHttpFetcherTest() {}
200c4acdf40033fc7bedba3ec6449b7a750b1fe5f24Alex Deymo  virtual ~AnyHttpFetcherTest() {}
2014348879380222dc8c74b0976e527bf3da66ba08fJay Srinivasan
202f28585764e91b7c25a7c2856ff645c8bb22d64a9Alex Deymo  virtual HttpFetcher* NewLargeFetcher(ProxyResolver* proxy_resolver) = 0;
203f28585764e91b7c25a7c2856ff645c8bb22d64a9Alex Deymo  HttpFetcher* NewLargeFetcher(size_t num_proxies) {
204f28585764e91b7c25a7c2856ff645c8bb22d64a9Alex Deymo    proxy_resolver_.set_num_proxies(num_proxies);
205f28585764e91b7c25a7c2856ff645c8bb22d64a9Alex Deymo    return NewLargeFetcher(&proxy_resolver_);
206f28585764e91b7c25a7c2856ff645c8bb22d64a9Alex Deymo  }
2079bedeb51f80c9547269eef6c2ec09596033bb818Gilad Arnold  HttpFetcher* NewLargeFetcher() {
2089bedeb51f80c9547269eef6c2ec09596033bb818Gilad Arnold    return NewLargeFetcher(1);
2099bedeb51f80c9547269eef6c2ec09596033bb818Gilad Arnold  }
2109bedeb51f80c9547269eef6c2ec09596033bb818Gilad Arnold
211f28585764e91b7c25a7c2856ff645c8bb22d64a9Alex Deymo  virtual HttpFetcher* NewSmallFetcher(ProxyResolver* proxy_resolver) = 0;
2129bedeb51f80c9547269eef6c2ec09596033bb818Gilad Arnold  HttpFetcher* NewSmallFetcher() {
213f28585764e91b7c25a7c2856ff645c8bb22d64a9Alex Deymo    proxy_resolver_.set_num_proxies(1);
214f28585764e91b7c25a7c2856ff645c8bb22d64a9Alex Deymo    return NewSmallFetcher(&proxy_resolver_);
2159bedeb51f80c9547269eef6c2ec09596033bb818Gilad Arnold  }
2169bedeb51f80c9547269eef6c2ec09596033bb818Gilad Arnold
217b6c562adec6e9491712f156f8fd50e2b807ff302Gilad Arnold  virtual string BigUrl(in_port_t port) const { return kUnusedUrl; }
218b6c562adec6e9491712f156f8fd50e2b807ff302Gilad Arnold  virtual string SmallUrl(in_port_t port) const { return kUnusedUrl; }
219b6c562adec6e9491712f156f8fd50e2b807ff302Gilad Arnold  virtual string ErrorUrl(in_port_t port) const { return kUnusedUrl; }
2209bedeb51f80c9547269eef6c2ec09596033bb818Gilad Arnold
2219bedeb51f80c9547269eef6c2ec09596033bb818Gilad Arnold  virtual bool IsMock() const = 0;
2229bedeb51f80c9547269eef6c2ec09596033bb818Gilad Arnold  virtual bool IsMulti() const = 0;
2236e3ffe73d27de744ef494292c003b5ba907799dfAlex Deymo  virtual bool IsHttpSupported() const = 0;
2249bedeb51f80c9547269eef6c2ec09596033bb818Gilad Arnold
2259bedeb51f80c9547269eef6c2ec09596033bb818Gilad Arnold  virtual void IgnoreServerAborting(HttpServer* server) const {}
2269bedeb51f80c9547269eef6c2ec09596033bb818Gilad Arnold
22760ca1a7bca7cc804ec80b510483081ef894de4cdAlex Deymo  virtual HttpServer* CreateServer() = 0;
2289bedeb51f80c9547269eef6c2ec09596033bb818Gilad Arnold
229c1c17b4ed6a3896b6343e737fd89682fa0c8436bAlex Deymo  FakeHardware* fake_hardware() {
230706a5abae125b8f5ba58a9b7e1e51570bbaa2089Alex Deymo    return &fake_hardware_;
231c1c17b4ed6a3896b6343e737fd89682fa0c8436bAlex Deymo  }
232c1c17b4ed6a3896b6343e737fd89682fa0c8436bAlex Deymo
2339bedeb51f80c9547269eef6c2ec09596033bb818Gilad Arnold protected:
2349bedeb51f80c9547269eef6c2ec09596033bb818Gilad Arnold  DirectProxyResolver proxy_resolver_;
235706a5abae125b8f5ba58a9b7e1e51570bbaa2089Alex Deymo  FakeHardware fake_hardware_;
2369bedeb51f80c9547269eef6c2ec09596033bb818Gilad Arnold};
2379bedeb51f80c9547269eef6c2ec09596033bb818Gilad Arnold
2389bedeb51f80c9547269eef6c2ec09596033bb818Gilad Arnoldclass MockHttpFetcherTest : public AnyHttpFetcherTest {
2399bedeb51f80c9547269eef6c2ec09596033bb818Gilad Arnold public:
2409bedeb51f80c9547269eef6c2ec09596033bb818Gilad Arnold  // Necessary to unhide the definition in the base class.
2419bedeb51f80c9547269eef6c2ec09596033bb818Gilad Arnold  using AnyHttpFetcherTest::NewLargeFetcher;
242f28585764e91b7c25a7c2856ff645c8bb22d64a9Alex Deymo  HttpFetcher* NewLargeFetcher(ProxyResolver* proxy_resolver) override {
2433f39d5cc753905874d8d93bef94f857b8808f19eAlex Vakulenko    brillo::Blob big_data(1000000);
2449bedeb51f80c9547269eef6c2ec09596033bb818Gilad Arnold    return new MockHttpFetcher(
245f28585764e91b7c25a7c2856ff645c8bb22d64a9Alex Deymo        big_data.data(), big_data.size(), proxy_resolver);
2469bedeb51f80c9547269eef6c2ec09596033bb818Gilad Arnold  }
2479bedeb51f80c9547269eef6c2ec09596033bb818Gilad Arnold
2489bedeb51f80c9547269eef6c2ec09596033bb818Gilad Arnold  // Necessary to unhide the definition in the base class.
2499bedeb51f80c9547269eef6c2ec09596033bb818Gilad Arnold  using AnyHttpFetcherTest::NewSmallFetcher;
250f28585764e91b7c25a7c2856ff645c8bb22d64a9Alex Deymo  HttpFetcher* NewSmallFetcher(ProxyResolver* proxy_resolver) override {
251f28585764e91b7c25a7c2856ff645c8bb22d64a9Alex Deymo    return new MockHttpFetcher("x", 1, proxy_resolver);
2529bedeb51f80c9547269eef6c2ec09596033bb818Gilad Arnold  }
2539bedeb51f80c9547269eef6c2ec09596033bb818Gilad Arnold
254610277efc6f7e5239158dfa4bb3b1021804326e0Alex Deymo  bool IsMock() const override { return true; }
255610277efc6f7e5239158dfa4bb3b1021804326e0Alex Deymo  bool IsMulti() const override { return false; }
2566e3ffe73d27de744ef494292c003b5ba907799dfAlex Deymo  bool IsHttpSupported() const override { return true; }
2579bedeb51f80c9547269eef6c2ec09596033bb818Gilad Arnold
25860ca1a7bca7cc804ec80b510483081ef894de4cdAlex Deymo  HttpServer* CreateServer() override {
2599bedeb51f80c9547269eef6c2ec09596033bb818Gilad Arnold    return new NullHttpServer;
2609bedeb51f80c9547269eef6c2ec09596033bb818Gilad Arnold  }
2619bedeb51f80c9547269eef6c2ec09596033bb818Gilad Arnold};
2629bedeb51f80c9547269eef6c2ec09596033bb818Gilad Arnold
2639bedeb51f80c9547269eef6c2ec09596033bb818Gilad Arnoldclass LibcurlHttpFetcherTest : public AnyHttpFetcherTest {
2649bedeb51f80c9547269eef6c2ec09596033bb818Gilad Arnold public:
2659bedeb51f80c9547269eef6c2ec09596033bb818Gilad Arnold  // Necessary to unhide the definition in the base class.
2669bedeb51f80c9547269eef6c2ec09596033bb818Gilad Arnold  using AnyHttpFetcherTest::NewLargeFetcher;
267f28585764e91b7c25a7c2856ff645c8bb22d64a9Alex Deymo  HttpFetcher* NewLargeFetcher(ProxyResolver* proxy_resolver) override {
268f28585764e91b7c25a7c2856ff645c8bb22d64a9Alex Deymo    LibcurlHttpFetcher* ret =
269f28585764e91b7c25a7c2856ff645c8bb22d64a9Alex Deymo        new LibcurlHttpFetcher(proxy_resolver, &fake_hardware_);
270b83371f6d7fc12a66d33eac614c0fae3aa0978baDarin Petkov    // Speed up test execution.
271b83371f6d7fc12a66d33eac614c0fae3aa0978baDarin Petkov    ret->set_idle_seconds(1);
272b83371f6d7fc12a66d33eac614c0fae3aa0978baDarin Petkov    ret->set_retry_seconds(1);
273706a5abae125b8f5ba58a9b7e1e51570bbaa2089Alex Deymo    fake_hardware_.SetIsOfficialBuild(false);
27449fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com    return ret;
27549fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com  }
2769bedeb51f80c9547269eef6c2ec09596033bb818Gilad Arnold
2779bedeb51f80c9547269eef6c2ec09596033bb818Gilad Arnold  // Necessary to unhide the definition in the base class.
2789bedeb51f80c9547269eef6c2ec09596033bb818Gilad Arnold  using AnyHttpFetcherTest::NewSmallFetcher;
279f28585764e91b7c25a7c2856ff645c8bb22d64a9Alex Deymo  HttpFetcher* NewSmallFetcher(ProxyResolver* proxy_resolver) override {
280f28585764e91b7c25a7c2856ff645c8bb22d64a9Alex Deymo    return NewLargeFetcher(proxy_resolver);
28149fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com  }
2829bedeb51f80c9547269eef6c2ec09596033bb818Gilad Arnold
283610277efc6f7e5239158dfa4bb3b1021804326e0Alex Deymo  string BigUrl(in_port_t port) const override {
284b6c562adec6e9491712f156f8fd50e2b807ff302Gilad Arnold    return LocalServerUrlForPath(port,
285b6c562adec6e9491712f156f8fd50e2b807ff302Gilad Arnold                                 base::StringPrintf("/download/%d",
2869bedeb51f80c9547269eef6c2ec09596033bb818Gilad Arnold                                                    kBigLength));
28749fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com  }
288610277efc6f7e5239158dfa4bb3b1021804326e0Alex Deymo  string SmallUrl(in_port_t port) const override {
289b6c562adec6e9491712f156f8fd50e2b807ff302Gilad Arnold    return LocalServerUrlForPath(port, "/foo");
29049fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com  }
291610277efc6f7e5239158dfa4bb3b1021804326e0Alex Deymo  string ErrorUrl(in_port_t port) const override {
292b6c562adec6e9491712f156f8fd50e2b807ff302Gilad Arnold    return LocalServerUrlForPath(port, "/error");
29348085ba58516e94f045d3ab7e26c8f36e6a6936fGilad Arnold  }
2949bedeb51f80c9547269eef6c2ec09596033bb818Gilad Arnold
295610277efc6f7e5239158dfa4bb3b1021804326e0Alex Deymo  bool IsMock() const override { return false; }
296610277efc6f7e5239158dfa4bb3b1021804326e0Alex Deymo  bool IsMulti() const override { return false; }
2976e3ffe73d27de744ef494292c003b5ba907799dfAlex Deymo  bool IsHttpSupported() const override { return true; }
2989bedeb51f80c9547269eef6c2ec09596033bb818Gilad Arnold
299610277efc6f7e5239158dfa4bb3b1021804326e0Alex Deymo  void IgnoreServerAborting(HttpServer* server) const override {
300b6c562adec6e9491712f156f8fd50e2b807ff302Gilad Arnold    // Nothing to do.
30108c4e27baaa7b40732b99642e1f21bf889d022efAndrew de los Reyes  }
3029bedeb51f80c9547269eef6c2ec09596033bb818Gilad Arnold
30360ca1a7bca7cc804ec80b510483081ef894de4cdAlex Deymo  HttpServer* CreateServer() override {
3049bedeb51f80c9547269eef6c2ec09596033bb818Gilad Arnold    return new PythonHttpServer;
3059bedeb51f80c9547269eef6c2ec09596033bb818Gilad Arnold  }
30649fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com};
30749fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com
3089bedeb51f80c9547269eef6c2ec09596033bb818Gilad Arnoldclass MultiRangeHttpFetcherTest : public LibcurlHttpFetcherTest {
3093fd5d30433509859bfdcc0b650e242981410c6a7Andrew de los Reyes public:
3109bedeb51f80c9547269eef6c2ec09596033bb818Gilad Arnold  // Necessary to unhide the definition in the base class.
3119bedeb51f80c9547269eef6c2ec09596033bb818Gilad Arnold  using AnyHttpFetcherTest::NewLargeFetcher;
312f28585764e91b7c25a7c2856ff645c8bb22d64a9Alex Deymo  HttpFetcher* NewLargeFetcher(ProxyResolver* proxy_resolver) override {
313f28585764e91b7c25a7c2856ff645c8bb22d64a9Alex Deymo    MultiRangeHttpFetcher* ret = new MultiRangeHttpFetcher(
314f28585764e91b7c25a7c2856ff645c8bb22d64a9Alex Deymo        new LibcurlHttpFetcher(proxy_resolver, &fake_hardware_));
315819fef2e0fa08984cf31e848e704442c500ea4f9Andrew de los Reyes    ret->ClearRanges();
316e4ad2508de4d69d7a90d3ce441efe2c82c55bd1dGilad Arnold    ret->AddRange(0);
3173fd5d30433509859bfdcc0b650e242981410c6a7Andrew de los Reyes    // Speed up test execution.
3183fd5d30433509859bfdcc0b650e242981410c6a7Andrew de los Reyes    ret->set_idle_seconds(1);
3193fd5d30433509859bfdcc0b650e242981410c6a7Andrew de los Reyes    ret->set_retry_seconds(1);
320706a5abae125b8f5ba58a9b7e1e51570bbaa2089Alex Deymo    fake_hardware_.SetIsOfficialBuild(false);
3213fd5d30433509859bfdcc0b650e242981410c6a7Andrew de los Reyes    return ret;
3223fd5d30433509859bfdcc0b650e242981410c6a7Andrew de los Reyes  }
3239bedeb51f80c9547269eef6c2ec09596033bb818Gilad Arnold
3249bedeb51f80c9547269eef6c2ec09596033bb818Gilad Arnold  // Necessary to unhide the definition in the base class.
3259bedeb51f80c9547269eef6c2ec09596033bb818Gilad Arnold  using AnyHttpFetcherTest::NewSmallFetcher;
326f28585764e91b7c25a7c2856ff645c8bb22d64a9Alex Deymo  HttpFetcher* NewSmallFetcher(ProxyResolver* proxy_resolver) override {
327f28585764e91b7c25a7c2856ff645c8bb22d64a9Alex Deymo    return NewLargeFetcher(proxy_resolver);
3289bedeb51f80c9547269eef6c2ec09596033bb818Gilad Arnold  }
3299bedeb51f80c9547269eef6c2ec09596033bb818Gilad Arnold
330610277efc6f7e5239158dfa4bb3b1021804326e0Alex Deymo  bool IsMulti() const override { return true; }
3319bedeb51f80c9547269eef6c2ec09596033bb818Gilad Arnold};
3329bedeb51f80c9547269eef6c2ec09596033bb818Gilad Arnold
3336e3ffe73d27de744ef494292c003b5ba907799dfAlex Deymoclass FileFetcherTest : public AnyHttpFetcherTest {
3346e3ffe73d27de744ef494292c003b5ba907799dfAlex Deymo public:
3356e3ffe73d27de744ef494292c003b5ba907799dfAlex Deymo  // Necessary to unhide the definition in the base class.
3366e3ffe73d27de744ef494292c003b5ba907799dfAlex Deymo  using AnyHttpFetcherTest::NewLargeFetcher;
3376e3ffe73d27de744ef494292c003b5ba907799dfAlex Deymo  HttpFetcher* NewLargeFetcher(ProxyResolver* /* proxy_resolver */) override {
3386e3ffe73d27de744ef494292c003b5ba907799dfAlex Deymo    return new FileFetcher();
3396e3ffe73d27de744ef494292c003b5ba907799dfAlex Deymo  }
3406e3ffe73d27de744ef494292c003b5ba907799dfAlex Deymo
3416e3ffe73d27de744ef494292c003b5ba907799dfAlex Deymo  // Necessary to unhide the definition in the base class.
3426e3ffe73d27de744ef494292c003b5ba907799dfAlex Deymo  using AnyHttpFetcherTest::NewSmallFetcher;
3436e3ffe73d27de744ef494292c003b5ba907799dfAlex Deymo  HttpFetcher* NewSmallFetcher(ProxyResolver* proxy_resolver) override {
3446e3ffe73d27de744ef494292c003b5ba907799dfAlex Deymo    return NewLargeFetcher(proxy_resolver);
3456e3ffe73d27de744ef494292c003b5ba907799dfAlex Deymo  }
3466e3ffe73d27de744ef494292c003b5ba907799dfAlex Deymo
3476e3ffe73d27de744ef494292c003b5ba907799dfAlex Deymo  string BigUrl(in_port_t port) const override {
3486e3ffe73d27de744ef494292c003b5ba907799dfAlex Deymo    return "file://" + temp_file_.path();
3496e3ffe73d27de744ef494292c003b5ba907799dfAlex Deymo  }
3506e3ffe73d27de744ef494292c003b5ba907799dfAlex Deymo  string SmallUrl(in_port_t port) const override {
3516e3ffe73d27de744ef494292c003b5ba907799dfAlex Deymo    test_utils::WriteFileString(temp_file_.path(), "small contents");
3526e3ffe73d27de744ef494292c003b5ba907799dfAlex Deymo    return "file://" + temp_file_.path();
3536e3ffe73d27de744ef494292c003b5ba907799dfAlex Deymo  }
3546e3ffe73d27de744ef494292c003b5ba907799dfAlex Deymo  string ErrorUrl(in_port_t port) const override {
3556e3ffe73d27de744ef494292c003b5ba907799dfAlex Deymo    return "file:///path/to/non-existing-file";
3566e3ffe73d27de744ef494292c003b5ba907799dfAlex Deymo  }
3576e3ffe73d27de744ef494292c003b5ba907799dfAlex Deymo
3586e3ffe73d27de744ef494292c003b5ba907799dfAlex Deymo  bool IsMock() const override { return false; }
3596e3ffe73d27de744ef494292c003b5ba907799dfAlex Deymo  bool IsMulti() const override { return false; }
3606e3ffe73d27de744ef494292c003b5ba907799dfAlex Deymo  bool IsHttpSupported() const override { return false; }
3616e3ffe73d27de744ef494292c003b5ba907799dfAlex Deymo
3626e3ffe73d27de744ef494292c003b5ba907799dfAlex Deymo  void IgnoreServerAborting(HttpServer* server) const override {}
3636e3ffe73d27de744ef494292c003b5ba907799dfAlex Deymo
3646e3ffe73d27de744ef494292c003b5ba907799dfAlex Deymo  HttpServer* CreateServer() override { return new NullHttpServer; }
3656e3ffe73d27de744ef494292c003b5ba907799dfAlex Deymo
3666e3ffe73d27de744ef494292c003b5ba907799dfAlex Deymo private:
3676e3ffe73d27de744ef494292c003b5ba907799dfAlex Deymo  test_utils::ScopedTempFile temp_file_{"ue_file_fetcher.XXXXXX"};
3686e3ffe73d27de744ef494292c003b5ba907799dfAlex Deymo};
3699bedeb51f80c9547269eef6c2ec09596033bb818Gilad Arnold
3709bedeb51f80c9547269eef6c2ec09596033bb818Gilad Arnold//
3719bedeb51f80c9547269eef6c2ec09596033bb818Gilad Arnold// Infrastructure for type tests of HTTP fetcher.
3729bedeb51f80c9547269eef6c2ec09596033bb818Gilad Arnold// See: http://code.google.com/p/googletest/wiki/AdvancedGuide#Typed_Tests
3739bedeb51f80c9547269eef6c2ec09596033bb818Gilad Arnold//
3749bedeb51f80c9547269eef6c2ec09596033bb818Gilad Arnold
3759bedeb51f80c9547269eef6c2ec09596033bb818Gilad Arnold// Fixture class template. We use an explicit constraint to guarantee that it
3769bedeb51f80c9547269eef6c2ec09596033bb818Gilad Arnold// can only be instantiated with an AnyHttpFetcherTest type, see:
3779bedeb51f80c9547269eef6c2ec09596033bb818Gilad Arnold// http://www2.research.att.com/~bs/bs_faq2.html#constraints
3789bedeb51f80c9547269eef6c2ec09596033bb818Gilad Arnoldtemplate <typename T>
3799bedeb51f80c9547269eef6c2ec09596033bb818Gilad Arnoldclass HttpFetcherTest : public ::testing::Test {
3809bedeb51f80c9547269eef6c2ec09596033bb818Gilad Arnold public:
381535f3b738b0bcbca23a6e361c84bf84145d6a3e6Alex Deymo  base::MessageLoopForIO base_loop_;
3823f39d5cc753905874d8d93bef94f857b8808f19eAlex Vakulenko  brillo::BaseMessageLoop loop_{&base_loop_};
38360ca1a7bca7cc804ec80b510483081ef894de4cdAlex Deymo
3849bedeb51f80c9547269eef6c2ec09596033bb818Gilad Arnold  T test_;
3859bedeb51f80c9547269eef6c2ec09596033bb818Gilad Arnold
38660ca1a7bca7cc804ec80b510483081ef894de4cdAlex Deymo protected:
38760ca1a7bca7cc804ec80b510483081ef894de4cdAlex Deymo  HttpFetcherTest() {
38860ca1a7bca7cc804ec80b510483081ef894de4cdAlex Deymo    loop_.SetAsCurrent();
38960ca1a7bca7cc804ec80b510483081ef894de4cdAlex Deymo  }
39060ca1a7bca7cc804ec80b510483081ef894de4cdAlex Deymo
39160ca1a7bca7cc804ec80b510483081ef894de4cdAlex Deymo  void TearDown() override {
3923f39d5cc753905874d8d93bef94f857b8808f19eAlex Vakulenko    EXPECT_EQ(0, brillo::MessageLoopRunMaxIterations(&loop_, 1));
39360ca1a7bca7cc804ec80b510483081ef894de4cdAlex Deymo  }
39460ca1a7bca7cc804ec80b510483081ef894de4cdAlex Deymo
3959bedeb51f80c9547269eef6c2ec09596033bb818Gilad Arnold private:
39660ca1a7bca7cc804ec80b510483081ef894de4cdAlex Deymo  static void TypeConstraint(T* a) {
3979bedeb51f80c9547269eef6c2ec09596033bb818Gilad Arnold    AnyHttpFetcherTest *b = a;
398d2779df63aaad8b65fc5d4badee7dbc9bed7f2b6Alex Vakulenko    if (b == 0)  // Silence compiler warning of unused variable.
3992dac5760bbad9db3b7a165806e9aa1d6a7a409abYunlian Jiang      *b = a;
4009bedeb51f80c9547269eef6c2ec09596033bb818Gilad Arnold  }
4013fd5d30433509859bfdcc0b650e242981410c6a7Andrew de los Reyes};
4023fd5d30433509859bfdcc0b650e242981410c6a7Andrew de los Reyes
4039bedeb51f80c9547269eef6c2ec09596033bb818Gilad Arnold// Test case types list.
4049bedeb51f80c9547269eef6c2ec09596033bb818Gilad Arnoldtypedef ::testing::Types<LibcurlHttpFetcherTest,
4059bedeb51f80c9547269eef6c2ec09596033bb818Gilad Arnold                         MockHttpFetcherTest,
4066e3ffe73d27de744ef494292c003b5ba907799dfAlex Deymo                         MultiRangeHttpFetcherTest,
4076e3ffe73d27de744ef494292c003b5ba907799dfAlex Deymo                         FileFetcherTest>
4086e3ffe73d27de744ef494292c003b5ba907799dfAlex Deymo    HttpFetcherTestTypes;
40949fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.comTYPED_TEST_CASE(HttpFetcherTest, HttpFetcherTestTypes);
41049fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com
4119bedeb51f80c9547269eef6c2ec09596033bb818Gilad Arnold
41249fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.comnamespace {
41349fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.comclass HttpFetcherTestDelegate : public HttpFetcherDelegate {
414c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com public:
4156f10c5f7c550b1bd6df1d9a04b5e75e03f943639Alex Deymo  HttpFetcherTestDelegate() = default;
41648085ba58516e94f045d3ab7e26c8f36e6a6936fGilad Arnold
417610277efc6f7e5239158dfa4bb3b1021804326e0Alex Deymo  void ReceivedBytes(HttpFetcher* /* fetcher */,
4186f10c5f7c550b1bd6df1d9a04b5e75e03f943639Alex Deymo                     const void* bytes,
4196f10c5f7c550b1bd6df1d9a04b5e75e03f943639Alex Deymo                     size_t length) override {
4206f10c5f7c550b1bd6df1d9a04b5e75e03f943639Alex Deymo    data.append(reinterpret_cast<const char*>(bytes), length);
42148085ba58516e94f045d3ab7e26c8f36e6a6936fGilad Arnold    // Update counters
42248085ba58516e94f045d3ab7e26c8f36e6a6936fGilad Arnold    times_received_bytes_called_++;
42349fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com  }
42448085ba58516e94f045d3ab7e26c8f36e6a6936fGilad Arnold
425610277efc6f7e5239158dfa4bb3b1021804326e0Alex Deymo  void TransferComplete(HttpFetcher* fetcher, bool successful) override {
42648085ba58516e94f045d3ab7e26c8f36e6a6936fGilad Arnold    if (is_expect_error_)
4279bedeb51f80c9547269eef6c2ec09596033bb818Gilad Arnold      EXPECT_EQ(kHttpResponseNotFound, fetcher->http_response_code());
42848085ba58516e94f045d3ab7e26c8f36e6a6936fGilad Arnold    else
4299bedeb51f80c9547269eef6c2ec09596033bb818Gilad Arnold      EXPECT_EQ(kHttpResponseOk, fetcher->http_response_code());
43060ca1a7bca7cc804ec80b510483081ef894de4cdAlex Deymo    MessageLoop::current()->BreakLoop();
43148085ba58516e94f045d3ab7e26c8f36e6a6936fGilad Arnold
43248085ba58516e94f045d3ab7e26c8f36e6a6936fGilad Arnold    // Update counter
43348085ba58516e94f045d3ab7e26c8f36e6a6936fGilad Arnold    times_transfer_complete_called_++;
43449fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com  }
43548085ba58516e94f045d3ab7e26c8f36e6a6936fGilad Arnold
436610277efc6f7e5239158dfa4bb3b1021804326e0Alex Deymo  void TransferTerminated(HttpFetcher* fetcher) override {
4379ce452b6acd95899e9adb17c2935012625163dc6Darin Petkov    ADD_FAILURE();
43848085ba58516e94f045d3ab7e26c8f36e6a6936fGilad Arnold    times_transfer_terminated_called_++;
4396e3ffe73d27de744ef494292c003b5ba907799dfAlex Deymo    MessageLoop::current()->BreakLoop();
4409ce452b6acd95899e9adb17c2935012625163dc6Darin Petkov  }
44148085ba58516e94f045d3ab7e26c8f36e6a6936fGilad Arnold
44248085ba58516e94f045d3ab7e26c8f36e6a6936fGilad Arnold  // Are we expecting an error response? (default: no)
4436f10c5f7c550b1bd6df1d9a04b5e75e03f943639Alex Deymo  bool is_expect_error_{false};
44448085ba58516e94f045d3ab7e26c8f36e6a6936fGilad Arnold
44548085ba58516e94f045d3ab7e26c8f36e6a6936fGilad Arnold  // Counters for callback invocations.
4466f10c5f7c550b1bd6df1d9a04b5e75e03f943639Alex Deymo  int times_transfer_complete_called_{0};
4476f10c5f7c550b1bd6df1d9a04b5e75e03f943639Alex Deymo  int times_transfer_terminated_called_{0};
4486f10c5f7c550b1bd6df1d9a04b5e75e03f943639Alex Deymo  int times_received_bytes_called_{0};
4496f10c5f7c550b1bd6df1d9a04b5e75e03f943639Alex Deymo
4506f10c5f7c550b1bd6df1d9a04b5e75e03f943639Alex Deymo  // The received data bytes.
4516f10c5f7c550b1bd6df1d9a04b5e75e03f943639Alex Deymo  string data;
45249fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com};
453c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com
454c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com
45560ca1a7bca7cc804ec80b510483081ef894de4cdAlex Deymovoid StartTransfer(HttpFetcher* http_fetcher, const string& url) {
45660ca1a7bca7cc804ec80b510483081ef894de4cdAlex Deymo  http_fetcher->BeginTransfer(url);
457c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com}
458d2779df63aaad8b65fc5d4badee7dbc9bed7f2b6Alex Vakulenko}  // namespace
45949fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com
46049fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.comTYPED_TEST(HttpFetcherTest, SimpleTest) {
46160ca1a7bca7cc804ec80b510483081ef894de4cdAlex Deymo  HttpFetcherTestDelegate delegate;
46260ca1a7bca7cc804ec80b510483081ef894de4cdAlex Deymo  unique_ptr<HttpFetcher> fetcher(this->test_.NewSmallFetcher());
46360ca1a7bca7cc804ec80b510483081ef894de4cdAlex Deymo  fetcher->set_delegate(&delegate);
46449fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com
46560ca1a7bca7cc804ec80b510483081ef894de4cdAlex Deymo  unique_ptr<HttpServer> server(this->test_.CreateServer());
46660ca1a7bca7cc804ec80b510483081ef894de4cdAlex Deymo  ASSERT_TRUE(server->started_);
467c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com
46860ca1a7bca7cc804ec80b510483081ef894de4cdAlex Deymo  this->loop_.PostTask(FROM_HERE, base::Bind(
46960ca1a7bca7cc804ec80b510483081ef894de4cdAlex Deymo      StartTransfer,
47060ca1a7bca7cc804ec80b510483081ef894de4cdAlex Deymo      fetcher.get(),
47160ca1a7bca7cc804ec80b510483081ef894de4cdAlex Deymo      this->test_.SmallUrl(server->GetPort())));
47260ca1a7bca7cc804ec80b510483081ef894de4cdAlex Deymo  this->loop_.Run();
47349fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com}
47449fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com
4753270f7411f55b872db385d0edffdfed18a684121Andrew de los ReyesTYPED_TEST(HttpFetcherTest, SimpleBigTest) {
47660ca1a7bca7cc804ec80b510483081ef894de4cdAlex Deymo  HttpFetcherTestDelegate delegate;
47760ca1a7bca7cc804ec80b510483081ef894de4cdAlex Deymo  unique_ptr<HttpFetcher> fetcher(this->test_.NewLargeFetcher());
47860ca1a7bca7cc804ec80b510483081ef894de4cdAlex Deymo  fetcher->set_delegate(&delegate);
4793270f7411f55b872db385d0edffdfed18a684121Andrew de los Reyes
48060ca1a7bca7cc804ec80b510483081ef894de4cdAlex Deymo  unique_ptr<HttpServer> server(this->test_.CreateServer());
48160ca1a7bca7cc804ec80b510483081ef894de4cdAlex Deymo  ASSERT_TRUE(server->started_);
4823270f7411f55b872db385d0edffdfed18a684121Andrew de los Reyes
48360ca1a7bca7cc804ec80b510483081ef894de4cdAlex Deymo  this->loop_.PostTask(FROM_HERE, base::Bind(
48460ca1a7bca7cc804ec80b510483081ef894de4cdAlex Deymo      StartTransfer,
48560ca1a7bca7cc804ec80b510483081ef894de4cdAlex Deymo      fetcher.get(),
48660ca1a7bca7cc804ec80b510483081ef894de4cdAlex Deymo      this->test_.BigUrl(server->GetPort())));
48760ca1a7bca7cc804ec80b510483081ef894de4cdAlex Deymo  this->loop_.Run();
4883270f7411f55b872db385d0edffdfed18a684121Andrew de los Reyes}
4893270f7411f55b872db385d0edffdfed18a684121Andrew de los Reyes
49048085ba58516e94f045d3ab7e26c8f36e6a6936fGilad Arnold// Issue #9648: when server returns an error HTTP response, the fetcher needs to
49148085ba58516e94f045d3ab7e26c8f36e6a6936fGilad Arnold// terminate transfer prematurely, rather than try to process the error payload.
49248085ba58516e94f045d3ab7e26c8f36e6a6936fGilad ArnoldTYPED_TEST(HttpFetcherTest, ErrorTest) {
4939bedeb51f80c9547269eef6c2ec09596033bb818Gilad Arnold  if (this->test_.IsMock() || this->test_.IsMulti())
49448085ba58516e94f045d3ab7e26c8f36e6a6936fGilad Arnold    return;
49560ca1a7bca7cc804ec80b510483081ef894de4cdAlex Deymo  HttpFetcherTestDelegate delegate;
49648085ba58516e94f045d3ab7e26c8f36e6a6936fGilad Arnold
49760ca1a7bca7cc804ec80b510483081ef894de4cdAlex Deymo  // Delegate should expect an error response.
49860ca1a7bca7cc804ec80b510483081ef894de4cdAlex Deymo  delegate.is_expect_error_ = true;
49948085ba58516e94f045d3ab7e26c8f36e6a6936fGilad Arnold
50060ca1a7bca7cc804ec80b510483081ef894de4cdAlex Deymo  unique_ptr<HttpFetcher> fetcher(this->test_.NewSmallFetcher());
50160ca1a7bca7cc804ec80b510483081ef894de4cdAlex Deymo  fetcher->set_delegate(&delegate);
50248085ba58516e94f045d3ab7e26c8f36e6a6936fGilad Arnold
50360ca1a7bca7cc804ec80b510483081ef894de4cdAlex Deymo  unique_ptr<HttpServer> server(this->test_.CreateServer());
50460ca1a7bca7cc804ec80b510483081ef894de4cdAlex Deymo  ASSERT_TRUE(server->started_);
50548085ba58516e94f045d3ab7e26c8f36e6a6936fGilad Arnold
50660ca1a7bca7cc804ec80b510483081ef894de4cdAlex Deymo  this->loop_.PostTask(FROM_HERE, base::Bind(
50760ca1a7bca7cc804ec80b510483081ef894de4cdAlex Deymo      StartTransfer,
5089bedeb51f80c9547269eef6c2ec09596033bb818Gilad Arnold      fetcher.get(),
50960ca1a7bca7cc804ec80b510483081ef894de4cdAlex Deymo      this->test_.ErrorUrl(server->GetPort())));
51060ca1a7bca7cc804ec80b510483081ef894de4cdAlex Deymo  this->loop_.Run();
51148085ba58516e94f045d3ab7e26c8f36e6a6936fGilad Arnold
51260ca1a7bca7cc804ec80b510483081ef894de4cdAlex Deymo  // Make sure that no bytes were received.
51360ca1a7bca7cc804ec80b510483081ef894de4cdAlex Deymo  CHECK_EQ(delegate.times_received_bytes_called_, 0);
51460ca1a7bca7cc804ec80b510483081ef894de4cdAlex Deymo  CHECK_EQ(fetcher->GetBytesDownloaded(), static_cast<size_t>(0));
51548085ba58516e94f045d3ab7e26c8f36e6a6936fGilad Arnold
51660ca1a7bca7cc804ec80b510483081ef894de4cdAlex Deymo  // Make sure that transfer completion was signaled once, and no termination
51760ca1a7bca7cc804ec80b510483081ef894de4cdAlex Deymo  // was signaled.
51860ca1a7bca7cc804ec80b510483081ef894de4cdAlex Deymo  CHECK_EQ(delegate.times_transfer_complete_called_, 1);
51960ca1a7bca7cc804ec80b510483081ef894de4cdAlex Deymo  CHECK_EQ(delegate.times_transfer_terminated_called_, 0);
52048085ba58516e94f045d3ab7e26c8f36e6a6936fGilad Arnold}
52148085ba58516e94f045d3ab7e26c8f36e6a6936fGilad Arnold
5226f10c5f7c550b1bd6df1d9a04b5e75e03f943639Alex DeymoTYPED_TEST(HttpFetcherTest, ExtraHeadersInRequestTest) {
5236e3ffe73d27de744ef494292c003b5ba907799dfAlex Deymo  if (this->test_.IsMock() || !this->test_.IsHttpSupported())
5246f10c5f7c550b1bd6df1d9a04b5e75e03f943639Alex Deymo    return;
5256f10c5f7c550b1bd6df1d9a04b5e75e03f943639Alex Deymo
5266f10c5f7c550b1bd6df1d9a04b5e75e03f943639Alex Deymo  HttpFetcherTestDelegate delegate;
5276f10c5f7c550b1bd6df1d9a04b5e75e03f943639Alex Deymo  unique_ptr<HttpFetcher> fetcher(this->test_.NewSmallFetcher());
5286f10c5f7c550b1bd6df1d9a04b5e75e03f943639Alex Deymo  fetcher->set_delegate(&delegate);
5296f10c5f7c550b1bd6df1d9a04b5e75e03f943639Alex Deymo  fetcher->SetHeader("User-Agent", "MyTest");
5306f10c5f7c550b1bd6df1d9a04b5e75e03f943639Alex Deymo  fetcher->SetHeader("user-agent", "Override that header");
5316f10c5f7c550b1bd6df1d9a04b5e75e03f943639Alex Deymo  fetcher->SetHeader("Authorization", "Basic user:passwd");
5326f10c5f7c550b1bd6df1d9a04b5e75e03f943639Alex Deymo
5336f10c5f7c550b1bd6df1d9a04b5e75e03f943639Alex Deymo  // Invalid headers.
5346f10c5f7c550b1bd6df1d9a04b5e75e03f943639Alex Deymo  fetcher->SetHeader("X-Foo", "Invalid\nHeader\nIgnored");
5356f10c5f7c550b1bd6df1d9a04b5e75e03f943639Alex Deymo  fetcher->SetHeader("X-Bar: ", "I do not know how to parse");
5366f10c5f7c550b1bd6df1d9a04b5e75e03f943639Alex Deymo
5376f10c5f7c550b1bd6df1d9a04b5e75e03f943639Alex Deymo  // Hide Accept header normally added by default.
5386f10c5f7c550b1bd6df1d9a04b5e75e03f943639Alex Deymo  fetcher->SetHeader("Accept", "");
5396f10c5f7c550b1bd6df1d9a04b5e75e03f943639Alex Deymo
5406f10c5f7c550b1bd6df1d9a04b5e75e03f943639Alex Deymo  PythonHttpServer server;
5416f10c5f7c550b1bd6df1d9a04b5e75e03f943639Alex Deymo  int port = server.GetPort();
5426f10c5f7c550b1bd6df1d9a04b5e75e03f943639Alex Deymo  ASSERT_TRUE(server.started_);
5436f10c5f7c550b1bd6df1d9a04b5e75e03f943639Alex Deymo
5446e3ffe73d27de744ef494292c003b5ba907799dfAlex Deymo  this->loop_.PostTask(
5456e3ffe73d27de744ef494292c003b5ba907799dfAlex Deymo      FROM_HERE,
5466e3ffe73d27de744ef494292c003b5ba907799dfAlex Deymo      base::Bind(StartTransfer,
5476e3ffe73d27de744ef494292c003b5ba907799dfAlex Deymo                 fetcher.get(),
5486e3ffe73d27de744ef494292c003b5ba907799dfAlex Deymo                 LocalServerUrlForPath(port, "/echo-headers")));
5496f10c5f7c550b1bd6df1d9a04b5e75e03f943639Alex Deymo  this->loop_.Run();
5506f10c5f7c550b1bd6df1d9a04b5e75e03f943639Alex Deymo
5516f10c5f7c550b1bd6df1d9a04b5e75e03f943639Alex Deymo  EXPECT_NE(string::npos,
5526f10c5f7c550b1bd6df1d9a04b5e75e03f943639Alex Deymo            delegate.data.find("user-agent: Override that header\r\n"));
5536f10c5f7c550b1bd6df1d9a04b5e75e03f943639Alex Deymo  EXPECT_NE(string::npos,
5546f10c5f7c550b1bd6df1d9a04b5e75e03f943639Alex Deymo            delegate.data.find("Authorization: Basic user:passwd\r\n"));
5556f10c5f7c550b1bd6df1d9a04b5e75e03f943639Alex Deymo
5566f10c5f7c550b1bd6df1d9a04b5e75e03f943639Alex Deymo  EXPECT_EQ(string::npos, delegate.data.find("\nAccept:"));
5576f10c5f7c550b1bd6df1d9a04b5e75e03f943639Alex Deymo  EXPECT_EQ(string::npos, delegate.data.find("X-Foo: Invalid"));
5586f10c5f7c550b1bd6df1d9a04b5e75e03f943639Alex Deymo  EXPECT_EQ(string::npos, delegate.data.find("X-Bar: I do not"));
5596f10c5f7c550b1bd6df1d9a04b5e75e03f943639Alex Deymo}
5606f10c5f7c550b1bd6df1d9a04b5e75e03f943639Alex Deymo
56149fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.comnamespace {
56249fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.comclass PausingHttpFetcherTestDelegate : public HttpFetcherDelegate {
56349fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com public:
564610277efc6f7e5239158dfa4bb3b1021804326e0Alex Deymo  void ReceivedBytes(HttpFetcher* fetcher,
565f68bbbc952aa9a71898e4939b5f36187fa564a50Alex Vakulenko                     const void* /* bytes */, size_t /* length */) override {
56649fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com    CHECK(!paused_);
56749fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com    paused_ = true;
56849fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com    fetcher->Pause();
56949fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com  }
570610277efc6f7e5239158dfa4bb3b1021804326e0Alex Deymo  void TransferComplete(HttpFetcher* fetcher, bool successful) override {
57160ca1a7bca7cc804ec80b510483081ef894de4cdAlex Deymo    MessageLoop::current()->BreakLoop();
57249fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com  }
573610277efc6f7e5239158dfa4bb3b1021804326e0Alex Deymo  void TransferTerminated(HttpFetcher* fetcher) override {
5749ce452b6acd95899e9adb17c2935012625163dc6Darin Petkov    ADD_FAILURE();
5759ce452b6acd95899e9adb17c2935012625163dc6Darin Petkov  }
57649fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com  void Unpause() {
57749fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com    CHECK(paused_);
57849fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com    paused_ = false;
57949fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com    fetcher_->Unpause();
58049fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com  }
58149fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com  bool paused_;
58249fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com  HttpFetcher* fetcher_;
58349fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com};
58449fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com
58560ca1a7bca7cc804ec80b510483081ef894de4cdAlex Deymovoid UnpausingTimeoutCallback(PausingHttpFetcherTestDelegate* delegate,
58660ca1a7bca7cc804ec80b510483081ef894de4cdAlex Deymo                              MessageLoop::TaskId* my_id) {
58749fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com  if (delegate->paused_)
58849fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com    delegate->Unpause();
58960ca1a7bca7cc804ec80b510483081ef894de4cdAlex Deymo  // Update the task id with the new scheduled callback.
59060ca1a7bca7cc804ec80b510483081ef894de4cdAlex Deymo  *my_id = MessageLoop::current()->PostDelayedTask(
59160ca1a7bca7cc804ec80b510483081ef894de4cdAlex Deymo      FROM_HERE,
59260ca1a7bca7cc804ec80b510483081ef894de4cdAlex Deymo      base::Bind(&UnpausingTimeoutCallback, delegate, my_id),
59360ca1a7bca7cc804ec80b510483081ef894de4cdAlex Deymo      base::TimeDelta::FromMilliseconds(200));
59449fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com}
595d2779df63aaad8b65fc5d4badee7dbc9bed7f2b6Alex Vakulenko}  // namespace
59649fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com
59749fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.comTYPED_TEST(HttpFetcherTest, PauseTest) {
598f28585764e91b7c25a7c2856ff645c8bb22d64a9Alex Deymo  PausingHttpFetcherTestDelegate delegate;
599f28585764e91b7c25a7c2856ff645c8bb22d64a9Alex Deymo  unique_ptr<HttpFetcher> fetcher(this->test_.NewLargeFetcher());
600f28585764e91b7c25a7c2856ff645c8bb22d64a9Alex Deymo  delegate.paused_ = false;
601f28585764e91b7c25a7c2856ff645c8bb22d64a9Alex Deymo  delegate.fetcher_ = fetcher.get();
602f28585764e91b7c25a7c2856ff645c8bb22d64a9Alex Deymo  fetcher->set_delegate(&delegate);
603f28585764e91b7c25a7c2856ff645c8bb22d64a9Alex Deymo
604f28585764e91b7c25a7c2856ff645c8bb22d64a9Alex Deymo  unique_ptr<HttpServer> server(this->test_.CreateServer());
605f28585764e91b7c25a7c2856ff645c8bb22d64a9Alex Deymo  ASSERT_TRUE(server->started_);
606f28585764e91b7c25a7c2856ff645c8bb22d64a9Alex Deymo
607f28585764e91b7c25a7c2856ff645c8bb22d64a9Alex Deymo  MessageLoop::TaskId callback_id;
608f28585764e91b7c25a7c2856ff645c8bb22d64a9Alex Deymo  callback_id = this->loop_.PostDelayedTask(
609f28585764e91b7c25a7c2856ff645c8bb22d64a9Alex Deymo      FROM_HERE,
610f28585764e91b7c25a7c2856ff645c8bb22d64a9Alex Deymo      base::Bind(&UnpausingTimeoutCallback, &delegate, &callback_id),
611f28585764e91b7c25a7c2856ff645c8bb22d64a9Alex Deymo      base::TimeDelta::FromMilliseconds(200));
612f28585764e91b7c25a7c2856ff645c8bb22d64a9Alex Deymo  fetcher->BeginTransfer(this->test_.BigUrl(server->GetPort()));
613f28585764e91b7c25a7c2856ff645c8bb22d64a9Alex Deymo
614f28585764e91b7c25a7c2856ff645c8bb22d64a9Alex Deymo  this->loop_.Run();
615f28585764e91b7c25a7c2856ff645c8bb22d64a9Alex Deymo  EXPECT_TRUE(this->loop_.CancelTask(callback_id));
616f28585764e91b7c25a7c2856ff645c8bb22d64a9Alex Deymo}
617f28585764e91b7c25a7c2856ff645c8bb22d64a9Alex Deymo
618f28585764e91b7c25a7c2856ff645c8bb22d64a9Alex Deymo// This test will pause the fetcher while the download is not yet started
619f28585764e91b7c25a7c2856ff645c8bb22d64a9Alex Deymo// because it is waiting for the proxy to be resolved.
620f28585764e91b7c25a7c2856ff645c8bb22d64a9Alex DeymoTYPED_TEST(HttpFetcherTest, PauseWhileResolvingProxyTest) {
6216e3ffe73d27de744ef494292c003b5ba907799dfAlex Deymo  if (this->test_.IsMock() || !this->test_.IsHttpSupported())
622f28585764e91b7c25a7c2856ff645c8bb22d64a9Alex Deymo    return;
623f28585764e91b7c25a7c2856ff645c8bb22d64a9Alex Deymo  MockProxyResolver mock_resolver;
624f28585764e91b7c25a7c2856ff645c8bb22d64a9Alex Deymo  unique_ptr<HttpFetcher> fetcher(this->test_.NewLargeFetcher(&mock_resolver));
625f28585764e91b7c25a7c2856ff645c8bb22d64a9Alex Deymo
626f28585764e91b7c25a7c2856ff645c8bb22d64a9Alex Deymo  // Saved arguments from the proxy call.
627f28585764e91b7c25a7c2856ff645c8bb22d64a9Alex Deymo  ProxiesResolvedFn proxy_callback = nullptr;
628f28585764e91b7c25a7c2856ff645c8bb22d64a9Alex Deymo  void* proxy_data = nullptr;
629f28585764e91b7c25a7c2856ff645c8bb22d64a9Alex Deymo
630f28585764e91b7c25a7c2856ff645c8bb22d64a9Alex Deymo  EXPECT_CALL(mock_resolver, GetProxiesForUrl("http://fake_url", _, _))
631f28585764e91b7c25a7c2856ff645c8bb22d64a9Alex Deymo      .WillOnce(DoAll(
632f28585764e91b7c25a7c2856ff645c8bb22d64a9Alex Deymo          SaveArg<1>(&proxy_callback), SaveArg<2>(&proxy_data), Return(true)));
633f28585764e91b7c25a7c2856ff645c8bb22d64a9Alex Deymo  fetcher->BeginTransfer("http://fake_url");
634f28585764e91b7c25a7c2856ff645c8bb22d64a9Alex Deymo  testing::Mock::VerifyAndClearExpectations(&mock_resolver);
635f28585764e91b7c25a7c2856ff645c8bb22d64a9Alex Deymo
636f28585764e91b7c25a7c2856ff645c8bb22d64a9Alex Deymo  // Pausing and unpausing while resolving the proxy should not affect anything.
637f28585764e91b7c25a7c2856ff645c8bb22d64a9Alex Deymo  fetcher->Pause();
638f28585764e91b7c25a7c2856ff645c8bb22d64a9Alex Deymo  fetcher->Unpause();
639f28585764e91b7c25a7c2856ff645c8bb22d64a9Alex Deymo  fetcher->Pause();
640f28585764e91b7c25a7c2856ff645c8bb22d64a9Alex Deymo  // Proxy resolver comes back after we paused the fetcher.
641f28585764e91b7c25a7c2856ff645c8bb22d64a9Alex Deymo  ASSERT_TRUE(proxy_callback);
642f28585764e91b7c25a7c2856ff645c8bb22d64a9Alex Deymo  (*proxy_callback)({1, kNoProxy}, proxy_data);
64349fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com}
64449fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com
64549fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.comnamespace {
64649fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.comclass AbortingHttpFetcherTestDelegate : public HttpFetcherDelegate {
64749fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com public:
648610277efc6f7e5239158dfa4bb3b1021804326e0Alex Deymo  void ReceivedBytes(HttpFetcher* fetcher,
649f68bbbc952aa9a71898e4939b5f36187fa564a50Alex Vakulenko                     const void* bytes, size_t length) override {}
650610277efc6f7e5239158dfa4bb3b1021804326e0Alex Deymo  void TransferComplete(HttpFetcher* fetcher, bool successful) override {
6519ce452b6acd95899e9adb17c2935012625163dc6Darin Petkov    ADD_FAILURE();  // We should never get here
65260ca1a7bca7cc804ec80b510483081ef894de4cdAlex Deymo    MessageLoop::current()->BreakLoop();
65349fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com  }
654610277efc6f7e5239158dfa4bb3b1021804326e0Alex Deymo  void TransferTerminated(HttpFetcher* fetcher) override {
6559ce452b6acd95899e9adb17c2935012625163dc6Darin Petkov    EXPECT_EQ(fetcher, fetcher_.get());
6569ce452b6acd95899e9adb17c2935012625163dc6Darin Petkov    EXPECT_FALSE(once_);
6579ce452b6acd95899e9adb17c2935012625163dc6Darin Petkov    EXPECT_TRUE(callback_once_);
6589ce452b6acd95899e9adb17c2935012625163dc6Darin Petkov    callback_once_ = false;
659c4acdf40033fc7bedba3ec6449b7a750b1fe5f24Alex Deymo    // The fetcher could have a callback scheduled on the ProxyResolver that
660c4acdf40033fc7bedba3ec6449b7a750b1fe5f24Alex Deymo    // can fire after this callback. We wait until the end of the test to
661c4acdf40033fc7bedba3ec6449b7a750b1fe5f24Alex Deymo    // delete the fetcher.
662819fef2e0fa08984cf31e848e704442c500ea4f9Andrew de los Reyes  }
66349fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com  void TerminateTransfer() {
66449fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com    CHECK(once_);
66549fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com    once_ = false;
66649fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com    fetcher_->TerminateTransfer();
66749fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com  }
66849fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com  void EndLoop() {
66960ca1a7bca7cc804ec80b510483081ef894de4cdAlex Deymo    MessageLoop::current()->BreakLoop();
67049fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com  }
67149fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com  bool once_;
6729ce452b6acd95899e9adb17c2935012625163dc6Darin Petkov  bool callback_once_;
67302f7c1dee242f490143791dbb73fa23fa3007cfaBen Chan  unique_ptr<HttpFetcher> fetcher_;
67449fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com};
67549fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com
67660ca1a7bca7cc804ec80b510483081ef894de4cdAlex Deymovoid AbortingTimeoutCallback(AbortingHttpFetcherTestDelegate* delegate,
67760ca1a7bca7cc804ec80b510483081ef894de4cdAlex Deymo                             MessageLoop::TaskId* my_id) {
67849fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com  if (delegate->once_) {
67949fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com    delegate->TerminateTransfer();
68060ca1a7bca7cc804ec80b510483081ef894de4cdAlex Deymo    *my_id = MessageLoop::current()->PostTask(
68160ca1a7bca7cc804ec80b510483081ef894de4cdAlex Deymo        FROM_HERE,
68260ca1a7bca7cc804ec80b510483081ef894de4cdAlex Deymo        base::Bind(AbortingTimeoutCallback, delegate, my_id));
68349fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com  } else {
68449fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com    delegate->EndLoop();
68560ca1a7bca7cc804ec80b510483081ef894de4cdAlex Deymo    *my_id = MessageLoop::kTaskIdNull;
68649fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com  }
68749fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com}
688d2779df63aaad8b65fc5d4badee7dbc9bed7f2b6Alex Vakulenko}  // namespace
68949fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com
69049fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.comTYPED_TEST(HttpFetcherTest, AbortTest) {
69160ca1a7bca7cc804ec80b510483081ef894de4cdAlex Deymo  AbortingHttpFetcherTestDelegate delegate;
69260ca1a7bca7cc804ec80b510483081ef894de4cdAlex Deymo  delegate.fetcher_.reset(this->test_.NewLargeFetcher());
69360ca1a7bca7cc804ec80b510483081ef894de4cdAlex Deymo  delegate.once_ = true;
69460ca1a7bca7cc804ec80b510483081ef894de4cdAlex Deymo  delegate.callback_once_ = true;
69560ca1a7bca7cc804ec80b510483081ef894de4cdAlex Deymo  delegate.fetcher_->set_delegate(&delegate);
69649fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com
69760ca1a7bca7cc804ec80b510483081ef894de4cdAlex Deymo  unique_ptr<HttpServer> server(this->test_.CreateServer());
69860ca1a7bca7cc804ec80b510483081ef894de4cdAlex Deymo  this->test_.IgnoreServerAborting(server.get());
69960ca1a7bca7cc804ec80b510483081ef894de4cdAlex Deymo  ASSERT_TRUE(server->started_);
7009bedeb51f80c9547269eef6c2ec09596033bb818Gilad Arnold
70160ca1a7bca7cc804ec80b510483081ef894de4cdAlex Deymo  MessageLoop::TaskId task_id = MessageLoop::kTaskIdNull;
70260ca1a7bca7cc804ec80b510483081ef894de4cdAlex Deymo
70360ca1a7bca7cc804ec80b510483081ef894de4cdAlex Deymo  task_id = this->loop_.PostTask(
70460ca1a7bca7cc804ec80b510483081ef894de4cdAlex Deymo      FROM_HERE,
70560ca1a7bca7cc804ec80b510483081ef894de4cdAlex Deymo      base::Bind(AbortingTimeoutCallback, &delegate, &task_id));
70660ca1a7bca7cc804ec80b510483081ef894de4cdAlex Deymo  delegate.fetcher_->BeginTransfer(this->test_.BigUrl(server->GetPort()));
70760ca1a7bca7cc804ec80b510483081ef894de4cdAlex Deymo
70860ca1a7bca7cc804ec80b510483081ef894de4cdAlex Deymo  this->loop_.Run();
70960ca1a7bca7cc804ec80b510483081ef894de4cdAlex Deymo  CHECK(!delegate.once_);
71060ca1a7bca7cc804ec80b510483081ef894de4cdAlex Deymo  CHECK(!delegate.callback_once_);
71160ca1a7bca7cc804ec80b510483081ef894de4cdAlex Deymo  this->loop_.CancelTask(task_id);
71249fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com}
71349fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com
714c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.comnamespace {
715c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.comclass FlakyHttpFetcherTestDelegate : public HttpFetcherDelegate {
716c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com public:
717610277efc6f7e5239158dfa4bb3b1021804326e0Alex Deymo  void ReceivedBytes(HttpFetcher* fetcher,
718f68bbbc952aa9a71898e4939b5f36187fa564a50Alex Vakulenko                     const void* bytes, size_t length) override {
719f68bbbc952aa9a71898e4939b5f36187fa564a50Alex Vakulenko    data.append(reinterpret_cast<const char*>(bytes), length);
720c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com  }
721610277efc6f7e5239158dfa4bb3b1021804326e0Alex Deymo  void TransferComplete(HttpFetcher* fetcher, bool successful) override {
722fb4ad7d5e8c5946fc475f3ee289b38287f015326Andrew de los Reyes    EXPECT_TRUE(successful);
7239bedeb51f80c9547269eef6c2ec09596033bb818Gilad Arnold    EXPECT_EQ(kHttpResponsePartialContent, fetcher->http_response_code());
72460ca1a7bca7cc804ec80b510483081ef894de4cdAlex Deymo    MessageLoop::current()->BreakLoop();
725c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com  }
726610277efc6f7e5239158dfa4bb3b1021804326e0Alex Deymo  void TransferTerminated(HttpFetcher* fetcher) override {
7279ce452b6acd95899e9adb17c2935012625163dc6Darin Petkov    ADD_FAILURE();
7289ce452b6acd95899e9adb17c2935012625163dc6Darin Petkov  }
729c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com  string data;
730c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com};
731d2779df63aaad8b65fc5d4badee7dbc9bed7f2b6Alex Vakulenko}  // namespace
732c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com
733c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.comTYPED_TEST(HttpFetcherTest, FlakyTest) {
7346e3ffe73d27de744ef494292c003b5ba907799dfAlex Deymo  if (this->test_.IsMock() || !this->test_.IsHttpSupported())
735c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com    return;
736c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com  {
737c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com    FlakyHttpFetcherTestDelegate delegate;
73802f7c1dee242f490143791dbb73fa23fa3007cfaBen Chan    unique_ptr<HttpFetcher> fetcher(this->test_.NewSmallFetcher());
739c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com    fetcher->set_delegate(&delegate);
740c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com
74102f7c1dee242f490143791dbb73fa23fa3007cfaBen Chan    unique_ptr<HttpServer> server(this->test_.CreateServer());
7429bedeb51f80c9547269eef6c2ec09596033bb818Gilad Arnold    ASSERT_TRUE(server->started_);
743c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com
74460ca1a7bca7cc804ec80b510483081ef894de4cdAlex Deymo    this->loop_.PostTask(FROM_HERE, base::Bind(
74560ca1a7bca7cc804ec80b510483081ef894de4cdAlex Deymo        &StartTransfer,
74660ca1a7bca7cc804ec80b510483081ef894de4cdAlex Deymo        fetcher.get(),
74760ca1a7bca7cc804ec80b510483081ef894de4cdAlex Deymo        LocalServerUrlForPath(server->GetPort(),
74860ca1a7bca7cc804ec80b510483081ef894de4cdAlex Deymo                              base::StringPrintf("/flaky/%d/%d/%d/%d",
74960ca1a7bca7cc804ec80b510483081ef894de4cdAlex Deymo                                                 kBigLength,
75060ca1a7bca7cc804ec80b510483081ef894de4cdAlex Deymo                                                 kFlakyTruncateLength,
75160ca1a7bca7cc804ec80b510483081ef894de4cdAlex Deymo                                                 kFlakySleepEvery,
75260ca1a7bca7cc804ec80b510483081ef894de4cdAlex Deymo                                                 kFlakySleepSecs))));
75360ca1a7bca7cc804ec80b510483081ef894de4cdAlex Deymo    this->loop_.Run();
754c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com
755c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com    // verify the data we get back
75680f70ff45f8ea9a679c0c3ed0dc143dd2fe2b63eAlex Deymo    ASSERT_EQ(kBigLength, static_cast<int>(delegate.data.size()));
7579bedeb51f80c9547269eef6c2ec09596033bb818Gilad Arnold    for (int i = 0; i < kBigLength; i += 10) {
758c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com      // Assert so that we don't flood the screen w/ EXPECT errors on failure.
759c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com      ASSERT_EQ(delegate.data.substr(i, 10), "abcdefghij");
760c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com    }
761c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com  }
762c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com}
763c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com
7649bbd18757660a09fb8831147b17916df8a3212e5Andrew de los Reyesnamespace {
7650a364bb65efa5c5cdcd49114080a646a39e030fcChris Sosa// This delegate kills the server attached to it after receiving any bytes.
7660a364bb65efa5c5cdcd49114080a646a39e030fcChris Sosa// This can be used for testing what happens when you try to fetch data and
7670a364bb65efa5c5cdcd49114080a646a39e030fcChris Sosa// the server dies.
7689bbd18757660a09fb8831147b17916df8a3212e5Andrew de los Reyesclass FailureHttpFetcherTestDelegate : public HttpFetcherDelegate {
7699bbd18757660a09fb8831147b17916df8a3212e5Andrew de los Reyes public:
770d2779df63aaad8b65fc5d4badee7dbc9bed7f2b6Alex Vakulenko  explicit FailureHttpFetcherTestDelegate(PythonHttpServer* server)
77160ca1a7bca7cc804ec80b510483081ef894de4cdAlex Deymo      : server_(server) {}
772135a58b2cc8bd94c384625d375f0bf26252d6f07Jay Srinivasan
773610277efc6f7e5239158dfa4bb3b1021804326e0Alex Deymo  ~FailureHttpFetcherTestDelegate() override {
774135a58b2cc8bd94c384625d375f0bf26252d6f07Jay Srinivasan    if (server_) {
775135a58b2cc8bd94c384625d375f0bf26252d6f07Jay Srinivasan      LOG(INFO) << "Stopping server in destructor";
776135a58b2cc8bd94c384625d375f0bf26252d6f07Jay Srinivasan      delete server_;
777135a58b2cc8bd94c384625d375f0bf26252d6f07Jay Srinivasan      LOG(INFO) << "server stopped";
778135a58b2cc8bd94c384625d375f0bf26252d6f07Jay Srinivasan    }
779135a58b2cc8bd94c384625d375f0bf26252d6f07Jay Srinivasan  }
780135a58b2cc8bd94c384625d375f0bf26252d6f07Jay Srinivasan
781610277efc6f7e5239158dfa4bb3b1021804326e0Alex Deymo  void ReceivedBytes(HttpFetcher* fetcher,
782f68bbbc952aa9a71898e4939b5f36187fa564a50Alex Vakulenko                     const void* bytes, size_t length) override {
7839bbd18757660a09fb8831147b17916df8a3212e5Andrew de los Reyes    if (server_) {
784135a58b2cc8bd94c384625d375f0bf26252d6f07Jay Srinivasan      LOG(INFO) << "Stopping server in ReceivedBytes";
7859bbd18757660a09fb8831147b17916df8a3212e5Andrew de los Reyes      delete server_;
7869bbd18757660a09fb8831147b17916df8a3212e5Andrew de los Reyes      LOG(INFO) << "server stopped";
78788b591f24cb3f94f982d7024c2e8ed25c2cc26a2Alex Vakulenko      server_ = nullptr;
7889bbd18757660a09fb8831147b17916df8a3212e5Andrew de los Reyes    }
7899bbd18757660a09fb8831147b17916df8a3212e5Andrew de los Reyes  }
790610277efc6f7e5239158dfa4bb3b1021804326e0Alex Deymo  void TransferComplete(HttpFetcher* fetcher, bool successful) override {
7919bbd18757660a09fb8831147b17916df8a3212e5Andrew de los Reyes    EXPECT_FALSE(successful);
7920a364bb65efa5c5cdcd49114080a646a39e030fcChris Sosa    EXPECT_EQ(0, fetcher->http_response_code());
79360ca1a7bca7cc804ec80b510483081ef894de4cdAlex Deymo    MessageLoop::current()->BreakLoop();
7949bbd18757660a09fb8831147b17916df8a3212e5Andrew de los Reyes  }
795610277efc6f7e5239158dfa4bb3b1021804326e0Alex Deymo  void TransferTerminated(HttpFetcher* fetcher) override {
7969ce452b6acd95899e9adb17c2935012625163dc6Darin Petkov    ADD_FAILURE();
7979ce452b6acd95899e9adb17c2935012625163dc6Darin Petkov  }
7989bbd18757660a09fb8831147b17916df8a3212e5Andrew de los Reyes  PythonHttpServer* server_;
7999bbd18757660a09fb8831147b17916df8a3212e5Andrew de los Reyes};
800d2779df63aaad8b65fc5d4badee7dbc9bed7f2b6Alex Vakulenko}  // namespace
8019bbd18757660a09fb8831147b17916df8a3212e5Andrew de los Reyes
8029bbd18757660a09fb8831147b17916df8a3212e5Andrew de los Reyes
8039bbd18757660a09fb8831147b17916df8a3212e5Andrew de los ReyesTYPED_TEST(HttpFetcherTest, FailureTest) {
8040a364bb65efa5c5cdcd49114080a646a39e030fcChris Sosa  // This test ensures that a fetcher responds correctly when a server isn't
8050a364bb65efa5c5cdcd49114080a646a39e030fcChris Sosa  // available at all.
8069bedeb51f80c9547269eef6c2ec09596033bb818Gilad Arnold  if (this->test_.IsMock())
8079bbd18757660a09fb8831147b17916df8a3212e5Andrew de los Reyes    return;
8089bbd18757660a09fb8831147b17916df8a3212e5Andrew de los Reyes  {
80988b591f24cb3f94f982d7024c2e8ed25c2cc26a2Alex Vakulenko    FailureHttpFetcherTestDelegate delegate(nullptr);
81002f7c1dee242f490143791dbb73fa23fa3007cfaBen Chan    unique_ptr<HttpFetcher> fetcher(this->test_.NewSmallFetcher());
8119bbd18757660a09fb8831147b17916df8a3212e5Andrew de los Reyes    fetcher->set_delegate(&delegate);
8129bbd18757660a09fb8831147b17916df8a3212e5Andrew de los Reyes
81360ca1a7bca7cc804ec80b510483081ef894de4cdAlex Deymo    this->loop_.PostTask(FROM_HERE,
81460ca1a7bca7cc804ec80b510483081ef894de4cdAlex Deymo                         base::Bind(StartTransfer,
81560ca1a7bca7cc804ec80b510483081ef894de4cdAlex Deymo                                    fetcher.get(),
81660ca1a7bca7cc804ec80b510483081ef894de4cdAlex Deymo                                    "http://host_doesnt_exist99999999"));
81760ca1a7bca7cc804ec80b510483081ef894de4cdAlex Deymo    this->loop_.Run();
8189bbd18757660a09fb8831147b17916df8a3212e5Andrew de los Reyes
8199bbd18757660a09fb8831147b17916df8a3212e5Andrew de los Reyes    // Exiting and testing happens in the delegate
8209bbd18757660a09fb8831147b17916df8a3212e5Andrew de los Reyes  }
8219bbd18757660a09fb8831147b17916df8a3212e5Andrew de los Reyes}
8229bbd18757660a09fb8831147b17916df8a3212e5Andrew de los Reyes
823f123ae2065ef19c172ae67a4c11cf23f1b787204Alex DeymoTYPED_TEST(HttpFetcherTest, NoResponseTest) {
824f123ae2065ef19c172ae67a4c11cf23f1b787204Alex Deymo  // This test starts a new http server but the server doesn't respond and just
825f123ae2065ef19c172ae67a4c11cf23f1b787204Alex Deymo  // closes the connection.
826f123ae2065ef19c172ae67a4c11cf23f1b787204Alex Deymo  if (this->test_.IsMock())
827f123ae2065ef19c172ae67a4c11cf23f1b787204Alex Deymo    return;
828f123ae2065ef19c172ae67a4c11cf23f1b787204Alex Deymo
829f123ae2065ef19c172ae67a4c11cf23f1b787204Alex Deymo  PythonHttpServer* server = new PythonHttpServer();
830f123ae2065ef19c172ae67a4c11cf23f1b787204Alex Deymo  int port = server->GetPort();
831f123ae2065ef19c172ae67a4c11cf23f1b787204Alex Deymo  ASSERT_TRUE(server->started_);
832f123ae2065ef19c172ae67a4c11cf23f1b787204Alex Deymo
833f123ae2065ef19c172ae67a4c11cf23f1b787204Alex Deymo  // Handles destruction and claims ownership.
834f123ae2065ef19c172ae67a4c11cf23f1b787204Alex Deymo  FailureHttpFetcherTestDelegate delegate(server);
835f123ae2065ef19c172ae67a4c11cf23f1b787204Alex Deymo  unique_ptr<HttpFetcher> fetcher(this->test_.NewSmallFetcher());
836f123ae2065ef19c172ae67a4c11cf23f1b787204Alex Deymo  fetcher->set_delegate(&delegate);
837f123ae2065ef19c172ae67a4c11cf23f1b787204Alex Deymo  // The server will not reply at all, so we can limit the execution time of the
838f123ae2065ef19c172ae67a4c11cf23f1b787204Alex Deymo  // test by reducing the low-speed timeout to something small. The test will
839f123ae2065ef19c172ae67a4c11cf23f1b787204Alex Deymo  // finish once the TimeoutCallback() triggers (every second) and the timeout
840f123ae2065ef19c172ae67a4c11cf23f1b787204Alex Deymo  // expired.
841f123ae2065ef19c172ae67a4c11cf23f1b787204Alex Deymo  fetcher->set_low_speed_limit(kDownloadLowSpeedLimitBps, 1);
842f123ae2065ef19c172ae67a4c11cf23f1b787204Alex Deymo
843f123ae2065ef19c172ae67a4c11cf23f1b787204Alex Deymo  this->loop_.PostTask(FROM_HERE, base::Bind(
844f123ae2065ef19c172ae67a4c11cf23f1b787204Alex Deymo      StartTransfer,
845f123ae2065ef19c172ae67a4c11cf23f1b787204Alex Deymo      fetcher.get(),
846f123ae2065ef19c172ae67a4c11cf23f1b787204Alex Deymo      LocalServerUrlForPath(port, "/hang")));
847f123ae2065ef19c172ae67a4c11cf23f1b787204Alex Deymo  this->loop_.Run();
848f123ae2065ef19c172ae67a4c11cf23f1b787204Alex Deymo
849f123ae2065ef19c172ae67a4c11cf23f1b787204Alex Deymo  // Check that no other callback runs in the next two seconds. That would
850f123ae2065ef19c172ae67a4c11cf23f1b787204Alex Deymo  // indicate a leaked callback.
851f123ae2065ef19c172ae67a4c11cf23f1b787204Alex Deymo  bool timeout = false;
852f123ae2065ef19c172ae67a4c11cf23f1b787204Alex Deymo  auto callback = base::Bind([&timeout]{ timeout = true;});
853f123ae2065ef19c172ae67a4c11cf23f1b787204Alex Deymo  this->loop_.PostDelayedTask(FROM_HERE, callback,
854f123ae2065ef19c172ae67a4c11cf23f1b787204Alex Deymo                              base::TimeDelta::FromSeconds(2));
855f123ae2065ef19c172ae67a4c11cf23f1b787204Alex Deymo  EXPECT_TRUE(this->loop_.RunOnce(true));
856f123ae2065ef19c172ae67a4c11cf23f1b787204Alex Deymo  EXPECT_TRUE(timeout);
857f123ae2065ef19c172ae67a4c11cf23f1b787204Alex Deymo}
858f123ae2065ef19c172ae67a4c11cf23f1b787204Alex Deymo
8599bbd18757660a09fb8831147b17916df8a3212e5Andrew de los ReyesTYPED_TEST(HttpFetcherTest, ServerDiesTest) {
8600a364bb65efa5c5cdcd49114080a646a39e030fcChris Sosa  // This test starts a new http server and kills it after receiving its first
8610a364bb65efa5c5cdcd49114080a646a39e030fcChris Sosa  // set of bytes. It test whether or not our fetcher eventually gives up on
8620a364bb65efa5c5cdcd49114080a646a39e030fcChris Sosa  // retries and aborts correctly.
8639bedeb51f80c9547269eef6c2ec09596033bb818Gilad Arnold  if (this->test_.IsMock())
8649bbd18757660a09fb8831147b17916df8a3212e5Andrew de los Reyes    return;
8659bbd18757660a09fb8831147b17916df8a3212e5Andrew de los Reyes  {
8660a364bb65efa5c5cdcd49114080a646a39e030fcChris Sosa    PythonHttpServer* server = new PythonHttpServer();
8670a364bb65efa5c5cdcd49114080a646a39e030fcChris Sosa    int port = server->GetPort();
8680a364bb65efa5c5cdcd49114080a646a39e030fcChris Sosa    ASSERT_TRUE(server->started_);
8690a364bb65efa5c5cdcd49114080a646a39e030fcChris Sosa
8700a364bb65efa5c5cdcd49114080a646a39e030fcChris Sosa    // Handles destruction and claims ownership.
8710a364bb65efa5c5cdcd49114080a646a39e030fcChris Sosa    FailureHttpFetcherTestDelegate delegate(server);
87202f7c1dee242f490143791dbb73fa23fa3007cfaBen Chan    unique_ptr<HttpFetcher> fetcher(this->test_.NewSmallFetcher());
8739bbd18757660a09fb8831147b17916df8a3212e5Andrew de los Reyes    fetcher->set_delegate(&delegate);
8749bbd18757660a09fb8831147b17916df8a3212e5Andrew de los Reyes
87560ca1a7bca7cc804ec80b510483081ef894de4cdAlex Deymo    this->loop_.PostTask(FROM_HERE, base::Bind(
87660ca1a7bca7cc804ec80b510483081ef894de4cdAlex Deymo        StartTransfer,
87760ca1a7bca7cc804ec80b510483081ef894de4cdAlex Deymo        fetcher.get(),
87860ca1a7bca7cc804ec80b510483081ef894de4cdAlex Deymo        LocalServerUrlForPath(port,
87960ca1a7bca7cc804ec80b510483081ef894de4cdAlex Deymo                              base::StringPrintf("/flaky/%d/%d/%d/%d",
88060ca1a7bca7cc804ec80b510483081ef894de4cdAlex Deymo                                                 kBigLength,
88160ca1a7bca7cc804ec80b510483081ef894de4cdAlex Deymo                                                 kFlakyTruncateLength,
88260ca1a7bca7cc804ec80b510483081ef894de4cdAlex Deymo                                                 kFlakySleepEvery,
88360ca1a7bca7cc804ec80b510483081ef894de4cdAlex Deymo                                                 kFlakySleepSecs))));
88460ca1a7bca7cc804ec80b510483081ef894de4cdAlex Deymo    this->loop_.Run();
8859bbd18757660a09fb8831147b17916df8a3212e5Andrew de los Reyes
8869bbd18757660a09fb8831147b17916df8a3212e5Andrew de los Reyes    // Exiting and testing happens in the delegate
8879bbd18757660a09fb8831147b17916df8a3212e5Andrew de los Reyes  }
8889bbd18757660a09fb8831147b17916df8a3212e5Andrew de los Reyes}
8899bbd18757660a09fb8831147b17916df8a3212e5Andrew de los Reyes
89041c2fcf4525a3b4e8960c4b71dfe4f4f11c8224fDarin Petkovnamespace {
8919bedeb51f80c9547269eef6c2ec09596033bb818Gilad Arnoldconst HttpResponseCode kRedirectCodes[] = {
8929bedeb51f80c9547269eef6c2ec09596033bb818Gilad Arnold  kHttpResponseMovedPermanently, kHttpResponseFound, kHttpResponseSeeOther,
8939bedeb51f80c9547269eef6c2ec09596033bb818Gilad Arnold  kHttpResponseTempRedirect
8949bedeb51f80c9547269eef6c2ec09596033bb818Gilad Arnold};
89541c2fcf4525a3b4e8960c4b71dfe4f4f11c8224fDarin Petkov
89641c2fcf4525a3b4e8960c4b71dfe4f4f11c8224fDarin Petkovclass RedirectHttpFetcherTestDelegate : public HttpFetcherDelegate {
89741c2fcf4525a3b4e8960c4b71dfe4f4f11c8224fDarin Petkov public:
898d2779df63aaad8b65fc5d4badee7dbc9bed7f2b6Alex Vakulenko  explicit RedirectHttpFetcherTestDelegate(bool expected_successful)
89941c2fcf4525a3b4e8960c4b71dfe4f4f11c8224fDarin Petkov      : expected_successful_(expected_successful) {}
900610277efc6f7e5239158dfa4bb3b1021804326e0Alex Deymo  void ReceivedBytes(HttpFetcher* fetcher,
901f68bbbc952aa9a71898e4939b5f36187fa564a50Alex Vakulenko                     const void* bytes, size_t length) override {
902f68bbbc952aa9a71898e4939b5f36187fa564a50Alex Vakulenko    data.append(reinterpret_cast<const char*>(bytes), length);
90341c2fcf4525a3b4e8960c4b71dfe4f4f11c8224fDarin Petkov  }
904610277efc6f7e5239158dfa4bb3b1021804326e0Alex Deymo  void TransferComplete(HttpFetcher* fetcher, bool successful) override {
90541c2fcf4525a3b4e8960c4b71dfe4f4f11c8224fDarin Petkov    EXPECT_EQ(expected_successful_, successful);
906d2779df63aaad8b65fc5d4badee7dbc9bed7f2b6Alex Vakulenko    if (expected_successful_) {
9079bedeb51f80c9547269eef6c2ec09596033bb818Gilad Arnold      EXPECT_EQ(kHttpResponseOk, fetcher->http_response_code());
908d2779df63aaad8b65fc5d4badee7dbc9bed7f2b6Alex Vakulenko    } else {
9099bedeb51f80c9547269eef6c2ec09596033bb818Gilad Arnold      EXPECT_GE(fetcher->http_response_code(), kHttpResponseMovedPermanently);
9109bedeb51f80c9547269eef6c2ec09596033bb818Gilad Arnold      EXPECT_LE(fetcher->http_response_code(), kHttpResponseTempRedirect);
911cb466212cccca21dfe0dcd01afbbb06e005309e2Darin Petkov    }
91260ca1a7bca7cc804ec80b510483081ef894de4cdAlex Deymo    MessageLoop::current()->BreakLoop();
91341c2fcf4525a3b4e8960c4b71dfe4f4f11c8224fDarin Petkov  }
914610277efc6f7e5239158dfa4bb3b1021804326e0Alex Deymo  void TransferTerminated(HttpFetcher* fetcher) override {
9159ce452b6acd95899e9adb17c2935012625163dc6Darin Petkov    ADD_FAILURE();
9169ce452b6acd95899e9adb17c2935012625163dc6Darin Petkov  }
91741c2fcf4525a3b4e8960c4b71dfe4f4f11c8224fDarin Petkov  bool expected_successful_;
91841c2fcf4525a3b4e8960c4b71dfe4f4f11c8224fDarin Petkov  string data;
91941c2fcf4525a3b4e8960c4b71dfe4f4f11c8224fDarin Petkov};
92041c2fcf4525a3b4e8960c4b71dfe4f4f11c8224fDarin Petkov
92141c2fcf4525a3b4e8960c4b71dfe4f4f11c8224fDarin Petkov// RedirectTest takes ownership of |http_fetcher|.
922b6c562adec6e9491712f156f8fd50e2b807ff302Gilad Arnoldvoid RedirectTest(const HttpServer* server,
923b6c562adec6e9491712f156f8fd50e2b807ff302Gilad Arnold                  bool expected_successful,
92441c2fcf4525a3b4e8960c4b71dfe4f4f11c8224fDarin Petkov                  const string& url,
92541c2fcf4525a3b4e8960c4b71dfe4f4f11c8224fDarin Petkov                  HttpFetcher* http_fetcher) {
92660ca1a7bca7cc804ec80b510483081ef894de4cdAlex Deymo  RedirectHttpFetcherTestDelegate delegate(expected_successful);
92760ca1a7bca7cc804ec80b510483081ef894de4cdAlex Deymo  unique_ptr<HttpFetcher> fetcher(http_fetcher);
92860ca1a7bca7cc804ec80b510483081ef894de4cdAlex Deymo  fetcher->set_delegate(&delegate);
929135a58b2cc8bd94c384625d375f0bf26252d6f07Jay Srinivasan
93060ca1a7bca7cc804ec80b510483081ef894de4cdAlex Deymo  MessageLoop::current()->PostTask(FROM_HERE, base::Bind(
93160ca1a7bca7cc804ec80b510483081ef894de4cdAlex Deymo      StartTransfer,
93260ca1a7bca7cc804ec80b510483081ef894de4cdAlex Deymo      fetcher.get(),
93360ca1a7bca7cc804ec80b510483081ef894de4cdAlex Deymo      LocalServerUrlForPath(server->GetPort(), url)));
93460ca1a7bca7cc804ec80b510483081ef894de4cdAlex Deymo  MessageLoop::current()->Run();
93560ca1a7bca7cc804ec80b510483081ef894de4cdAlex Deymo  if (expected_successful) {
93660ca1a7bca7cc804ec80b510483081ef894de4cdAlex Deymo    // verify the data we get back
93780f70ff45f8ea9a679c0c3ed0dc143dd2fe2b63eAlex Deymo    ASSERT_EQ(static_cast<size_t>(kMediumLength), delegate.data.size());
93860ca1a7bca7cc804ec80b510483081ef894de4cdAlex Deymo    for (int i = 0; i < kMediumLength; i += 10) {
93960ca1a7bca7cc804ec80b510483081ef894de4cdAlex Deymo      // Assert so that we don't flood the screen w/ EXPECT errors on failure.
94060ca1a7bca7cc804ec80b510483081ef894de4cdAlex Deymo      ASSERT_EQ(delegate.data.substr(i, 10), "abcdefghij");
94141c2fcf4525a3b4e8960c4b71dfe4f4f11c8224fDarin Petkov    }
94241c2fcf4525a3b4e8960c4b71dfe4f4f11c8224fDarin Petkov  }
94341c2fcf4525a3b4e8960c4b71dfe4f4f11c8224fDarin Petkov}
944d2779df63aaad8b65fc5d4badee7dbc9bed7f2b6Alex Vakulenko}  // namespace
94541c2fcf4525a3b4e8960c4b71dfe4f4f11c8224fDarin Petkov
94641c2fcf4525a3b4e8960c4b71dfe4f4f11c8224fDarin PetkovTYPED_TEST(HttpFetcherTest, SimpleRedirectTest) {
9476e3ffe73d27de744ef494292c003b5ba907799dfAlex Deymo  if (this->test_.IsMock() || !this->test_.IsHttpSupported())
94841c2fcf4525a3b4e8960c4b71dfe4f4f11c8224fDarin Petkov    return;
9499bedeb51f80c9547269eef6c2ec09596033bb818Gilad Arnold
95002f7c1dee242f490143791dbb73fa23fa3007cfaBen Chan  unique_ptr<HttpServer> server(this->test_.CreateServer());
9519bedeb51f80c9547269eef6c2ec09596033bb818Gilad Arnold  ASSERT_TRUE(server->started_);
9529bedeb51f80c9547269eef6c2ec09596033bb818Gilad Arnold
95341c2fcf4525a3b4e8960c4b71dfe4f4f11c8224fDarin Petkov  for (size_t c = 0; c < arraysize(kRedirectCodes); ++c) {
9549bedeb51f80c9547269eef6c2ec09596033bb818Gilad Arnold    const string url = base::StringPrintf("/redirect/%d/download/%d",
9559bedeb51f80c9547269eef6c2ec09596033bb818Gilad Arnold                                          kRedirectCodes[c],
9569bedeb51f80c9547269eef6c2ec09596033bb818Gilad Arnold                                          kMediumLength);
957b6c562adec6e9491712f156f8fd50e2b807ff302Gilad Arnold    RedirectTest(server.get(), true, url, this->test_.NewLargeFetcher());
95841c2fcf4525a3b4e8960c4b71dfe4f4f11c8224fDarin Petkov  }
95941c2fcf4525a3b4e8960c4b71dfe4f4f11c8224fDarin Petkov}
96041c2fcf4525a3b4e8960c4b71dfe4f4f11c8224fDarin Petkov
96141c2fcf4525a3b4e8960c4b71dfe4f4f11c8224fDarin PetkovTYPED_TEST(HttpFetcherTest, MaxRedirectTest) {
9626e3ffe73d27de744ef494292c003b5ba907799dfAlex Deymo  if (this->test_.IsMock() || !this->test_.IsHttpSupported())
96341c2fcf4525a3b4e8960c4b71dfe4f4f11c8224fDarin Petkov    return;
9649bedeb51f80c9547269eef6c2ec09596033bb818Gilad Arnold
96502f7c1dee242f490143791dbb73fa23fa3007cfaBen Chan  unique_ptr<HttpServer> server(this->test_.CreateServer());
9669bedeb51f80c9547269eef6c2ec09596033bb818Gilad Arnold  ASSERT_TRUE(server->started_);
9679bedeb51f80c9547269eef6c2ec09596033bb818Gilad Arnold
96841c2fcf4525a3b4e8960c4b71dfe4f4f11c8224fDarin Petkov  string url;
96934135a9f24c72137aa85378b57e7698162c687f2David Zeuthen  for (int r = 0; r < kDownloadMaxRedirects; r++) {
97041c2fcf4525a3b4e8960c4b71dfe4f4f11c8224fDarin Petkov    url += base::StringPrintf("/redirect/%d",
97141c2fcf4525a3b4e8960c4b71dfe4f4f11c8224fDarin Petkov                              kRedirectCodes[r % arraysize(kRedirectCodes)]);
97241c2fcf4525a3b4e8960c4b71dfe4f4f11c8224fDarin Petkov  }
9739bedeb51f80c9547269eef6c2ec09596033bb818Gilad Arnold  url += base::StringPrintf("/download/%d", kMediumLength);
974b6c562adec6e9491712f156f8fd50e2b807ff302Gilad Arnold  RedirectTest(server.get(), true, url, this->test_.NewLargeFetcher());
97541c2fcf4525a3b4e8960c4b71dfe4f4f11c8224fDarin Petkov}
97641c2fcf4525a3b4e8960c4b71dfe4f4f11c8224fDarin Petkov
97741c2fcf4525a3b4e8960c4b71dfe4f4f11c8224fDarin PetkovTYPED_TEST(HttpFetcherTest, BeyondMaxRedirectTest) {
9786e3ffe73d27de744ef494292c003b5ba907799dfAlex Deymo  if (this->test_.IsMock() || !this->test_.IsHttpSupported())
97941c2fcf4525a3b4e8960c4b71dfe4f4f11c8224fDarin Petkov    return;
9809bedeb51f80c9547269eef6c2ec09596033bb818Gilad Arnold
98102f7c1dee242f490143791dbb73fa23fa3007cfaBen Chan  unique_ptr<HttpServer> server(this->test_.CreateServer());
9829bedeb51f80c9547269eef6c2ec09596033bb818Gilad Arnold  ASSERT_TRUE(server->started_);
9839bedeb51f80c9547269eef6c2ec09596033bb818Gilad Arnold
98441c2fcf4525a3b4e8960c4b71dfe4f4f11c8224fDarin Petkov  string url;
98534135a9f24c72137aa85378b57e7698162c687f2David Zeuthen  for (int r = 0; r < kDownloadMaxRedirects + 1; r++) {
98641c2fcf4525a3b4e8960c4b71dfe4f4f11c8224fDarin Petkov    url += base::StringPrintf("/redirect/%d",
98741c2fcf4525a3b4e8960c4b71dfe4f4f11c8224fDarin Petkov                              kRedirectCodes[r % arraysize(kRedirectCodes)]);
98841c2fcf4525a3b4e8960c4b71dfe4f4f11c8224fDarin Petkov  }
9899bedeb51f80c9547269eef6c2ec09596033bb818Gilad Arnold  url += base::StringPrintf("/download/%d", kMediumLength);
990b6c562adec6e9491712f156f8fd50e2b807ff302Gilad Arnold  RedirectTest(server.get(), false, url, this->test_.NewLargeFetcher());
99141c2fcf4525a3b4e8960c4b71dfe4f4f11c8224fDarin Petkov}
99241c2fcf4525a3b4e8960c4b71dfe4f4f11c8224fDarin Petkov
9933fd5d30433509859bfdcc0b650e242981410c6a7Andrew de los Reyesnamespace {
9943fd5d30433509859bfdcc0b650e242981410c6a7Andrew de los Reyesclass MultiHttpFetcherTestDelegate : public HttpFetcherDelegate {
9953fd5d30433509859bfdcc0b650e242981410c6a7Andrew de los Reyes public:
996d2779df63aaad8b65fc5d4badee7dbc9bed7f2b6Alex Vakulenko  explicit MultiHttpFetcherTestDelegate(int expected_response_code)
9973fd5d30433509859bfdcc0b650e242981410c6a7Andrew de los Reyes      : expected_response_code_(expected_response_code) {}
998e4ad2508de4d69d7a90d3ce441efe2c82c55bd1dGilad Arnold
999610277efc6f7e5239158dfa4bb3b1021804326e0Alex Deymo  void ReceivedBytes(HttpFetcher* fetcher,
1000f68bbbc952aa9a71898e4939b5f36187fa564a50Alex Vakulenko                     const void* bytes, size_t length) override {
10019ce452b6acd95899e9adb17c2935012625163dc6Darin Petkov    EXPECT_EQ(fetcher, fetcher_.get());
1002f68bbbc952aa9a71898e4939b5f36187fa564a50Alex Vakulenko    data.append(reinterpret_cast<const char*>(bytes), length);
10033fd5d30433509859bfdcc0b650e242981410c6a7Andrew de los Reyes  }
1004e4ad2508de4d69d7a90d3ce441efe2c82c55bd1dGilad Arnold
1005610277efc6f7e5239158dfa4bb3b1021804326e0Alex Deymo  void TransferComplete(HttpFetcher* fetcher, bool successful) override {
10069ce452b6acd95899e9adb17c2935012625163dc6Darin Petkov    EXPECT_EQ(fetcher, fetcher_.get());
10079bedeb51f80c9547269eef6c2ec09596033bb818Gilad Arnold    EXPECT_EQ(expected_response_code_ != kHttpResponseUndefined, successful);
10083fd5d30433509859bfdcc0b650e242981410c6a7Andrew de los Reyes    if (expected_response_code_ != 0)
10093fd5d30433509859bfdcc0b650e242981410c6a7Andrew de los Reyes      EXPECT_EQ(expected_response_code_, fetcher->http_response_code());
10109ce452b6acd95899e9adb17c2935012625163dc6Darin Petkov    // Destroy the fetcher (because we're allowed to).
101188b591f24cb3f94f982d7024c2e8ed25c2cc26a2Alex Vakulenko    fetcher_.reset(nullptr);
101260ca1a7bca7cc804ec80b510483081ef894de4cdAlex Deymo    MessageLoop::current()->BreakLoop();
10133fd5d30433509859bfdcc0b650e242981410c6a7Andrew de los Reyes  }
1014e4ad2508de4d69d7a90d3ce441efe2c82c55bd1dGilad Arnold
1015610277efc6f7e5239158dfa4bb3b1021804326e0Alex Deymo  void TransferTerminated(HttpFetcher* fetcher) override {
10169ce452b6acd95899e9adb17c2935012625163dc6Darin Petkov    ADD_FAILURE();
10179ce452b6acd95899e9adb17c2935012625163dc6Darin Petkov  }
1018e4ad2508de4d69d7a90d3ce441efe2c82c55bd1dGilad Arnold
101902f7c1dee242f490143791dbb73fa23fa3007cfaBen Chan  unique_ptr<HttpFetcher> fetcher_;
10203fd5d30433509859bfdcc0b650e242981410c6a7Andrew de los Reyes  int expected_response_code_;
10213fd5d30433509859bfdcc0b650e242981410c6a7Andrew de los Reyes  string data;
10223fd5d30433509859bfdcc0b650e242981410c6a7Andrew de los Reyes};
10233fd5d30433509859bfdcc0b650e242981410c6a7Andrew de los Reyes
10243fd5d30433509859bfdcc0b650e242981410c6a7Andrew de los Reyesvoid MultiTest(HttpFetcher* fetcher_in,
1025c1c17b4ed6a3896b6343e737fd89682fa0c8436bAlex Deymo               FakeHardware* fake_hardware,
10263fd5d30433509859bfdcc0b650e242981410c6a7Andrew de los Reyes               const string& url,
1027f9cb98c0cacccca803db48502c7bd461d04cb6b0Ben Chan               const vector<pair<off_t, off_t>>& ranges,
10283fd5d30433509859bfdcc0b650e242981410c6a7Andrew de los Reyes               const string& expected_prefix,
10295fe0c4ede81b82ae3425ddbbb698eceef14cbc78Alex Deymo               size_t expected_size,
10309bedeb51f80c9547269eef6c2ec09596033bb818Gilad Arnold               HttpResponseCode expected_response_code) {
103160ca1a7bca7cc804ec80b510483081ef894de4cdAlex Deymo  MultiHttpFetcherTestDelegate delegate(expected_response_code);
103260ca1a7bca7cc804ec80b510483081ef894de4cdAlex Deymo  delegate.fetcher_.reset(fetcher_in);
103360ca1a7bca7cc804ec80b510483081ef894de4cdAlex Deymo
103460ca1a7bca7cc804ec80b510483081ef894de4cdAlex Deymo  MultiRangeHttpFetcher* multi_fetcher =
103580f70ff45f8ea9a679c0c3ed0dc143dd2fe2b63eAlex Deymo      static_cast<MultiRangeHttpFetcher*>(fetcher_in);
103660ca1a7bca7cc804ec80b510483081ef894de4cdAlex Deymo  ASSERT_TRUE(multi_fetcher);
103760ca1a7bca7cc804ec80b510483081ef894de4cdAlex Deymo  multi_fetcher->ClearRanges();
103860ca1a7bca7cc804ec80b510483081ef894de4cdAlex Deymo  for (vector<pair<off_t, off_t>>::const_iterator it = ranges.begin(),
103960ca1a7bca7cc804ec80b510483081ef894de4cdAlex Deymo           e = ranges.end(); it != e; ++it) {
104060ca1a7bca7cc804ec80b510483081ef894de4cdAlex Deymo    string tmp_str = base::StringPrintf("%jd+", it->first);
104160ca1a7bca7cc804ec80b510483081ef894de4cdAlex Deymo    if (it->second > 0) {
104260ca1a7bca7cc804ec80b510483081ef894de4cdAlex Deymo      base::StringAppendF(&tmp_str, "%jd", it->second);
104360ca1a7bca7cc804ec80b510483081ef894de4cdAlex Deymo      multi_fetcher->AddRange(it->first, it->second);
104460ca1a7bca7cc804ec80b510483081ef894de4cdAlex Deymo    } else {
104560ca1a7bca7cc804ec80b510483081ef894de4cdAlex Deymo      base::StringAppendF(&tmp_str, "?");
104660ca1a7bca7cc804ec80b510483081ef894de4cdAlex Deymo      multi_fetcher->AddRange(it->first);
1047819fef2e0fa08984cf31e848e704442c500ea4f9Andrew de los Reyes    }
104860ca1a7bca7cc804ec80b510483081ef894de4cdAlex Deymo    LOG(INFO) << "added range: " << tmp_str;
104960ca1a7bca7cc804ec80b510483081ef894de4cdAlex Deymo  }
1050c1c17b4ed6a3896b6343e737fd89682fa0c8436bAlex Deymo  fake_hardware->SetIsOfficialBuild(false);
105160ca1a7bca7cc804ec80b510483081ef894de4cdAlex Deymo  multi_fetcher->set_delegate(&delegate);
10523fd5d30433509859bfdcc0b650e242981410c6a7Andrew de los Reyes
105360ca1a7bca7cc804ec80b510483081ef894de4cdAlex Deymo  MessageLoop::current()->PostTask(
105460ca1a7bca7cc804ec80b510483081ef894de4cdAlex Deymo      FROM_HERE,
105560ca1a7bca7cc804ec80b510483081ef894de4cdAlex Deymo      base::Bind(StartTransfer, multi_fetcher, url));
105660ca1a7bca7cc804ec80b510483081ef894de4cdAlex Deymo  MessageLoop::current()->Run();
10573fd5d30433509859bfdcc0b650e242981410c6a7Andrew de los Reyes
105860ca1a7bca7cc804ec80b510483081ef894de4cdAlex Deymo  EXPECT_EQ(expected_size, delegate.data.size());
105960ca1a7bca7cc804ec80b510483081ef894de4cdAlex Deymo  EXPECT_EQ(expected_prefix,
106060ca1a7bca7cc804ec80b510483081ef894de4cdAlex Deymo            string(delegate.data.data(), expected_prefix.size()));
10613fd5d30433509859bfdcc0b650e242981410c6a7Andrew de los Reyes}
1062d2779df63aaad8b65fc5d4badee7dbc9bed7f2b6Alex Vakulenko}  // namespace
10633fd5d30433509859bfdcc0b650e242981410c6a7Andrew de los Reyes
10649ce452b6acd95899e9adb17c2935012625163dc6Darin PetkovTYPED_TEST(HttpFetcherTest, MultiHttpFetcherSimpleTest) {
10659bedeb51f80c9547269eef6c2ec09596033bb818Gilad Arnold  if (!this->test_.IsMulti())
10663fd5d30433509859bfdcc0b650e242981410c6a7Andrew de los Reyes    return;
10679bedeb51f80c9547269eef6c2ec09596033bb818Gilad Arnold
106802f7c1dee242f490143791dbb73fa23fa3007cfaBen Chan  unique_ptr<HttpServer> server(this->test_.CreateServer());
10699bedeb51f80c9547269eef6c2ec09596033bb818Gilad Arnold  ASSERT_TRUE(server->started_);
10703fd5d30433509859bfdcc0b650e242981410c6a7Andrew de los Reyes
1071f9cb98c0cacccca803db48502c7bd461d04cb6b0Ben Chan  vector<pair<off_t, off_t>> ranges;
10723fd5d30433509859bfdcc0b650e242981410c6a7Andrew de los Reyes  ranges.push_back(make_pair(0, 25));
1073e4ad2508de4d69d7a90d3ce441efe2c82c55bd1dGilad Arnold  ranges.push_back(make_pair(99, 0));
10749bedeb51f80c9547269eef6c2ec09596033bb818Gilad Arnold  MultiTest(this->test_.NewLargeFetcher(),
1075c1c17b4ed6a3896b6343e737fd89682fa0c8436bAlex Deymo            this->test_.fake_hardware(),
1076b6c562adec6e9491712f156f8fd50e2b807ff302Gilad Arnold            this->test_.BigUrl(server->GetPort()),
10773fd5d30433509859bfdcc0b650e242981410c6a7Andrew de los Reyes            ranges,
10783fd5d30433509859bfdcc0b650e242981410c6a7Andrew de los Reyes            "abcdefghijabcdefghijabcdejabcdefghijabcdef",
10799bedeb51f80c9547269eef6c2ec09596033bb818Gilad Arnold            kBigLength - (99 - 25),
10809bedeb51f80c9547269eef6c2ec09596033bb818Gilad Arnold            kHttpResponsePartialContent);
10813fd5d30433509859bfdcc0b650e242981410c6a7Andrew de los Reyes}
10823fd5d30433509859bfdcc0b650e242981410c6a7Andrew de los Reyes
10833fd5d30433509859bfdcc0b650e242981410c6a7Andrew de los ReyesTYPED_TEST(HttpFetcherTest, MultiHttpFetcherLengthLimitTest) {
10849bedeb51f80c9547269eef6c2ec09596033bb818Gilad Arnold  if (!this->test_.IsMulti())
10853fd5d30433509859bfdcc0b650e242981410c6a7Andrew de los Reyes    return;
10869bedeb51f80c9547269eef6c2ec09596033bb818Gilad Arnold
108702f7c1dee242f490143791dbb73fa23fa3007cfaBen Chan  unique_ptr<HttpServer> server(this->test_.CreateServer());
10889bedeb51f80c9547269eef6c2ec09596033bb818Gilad Arnold  ASSERT_TRUE(server->started_);
10893fd5d30433509859bfdcc0b650e242981410c6a7Andrew de los Reyes
1090f9cb98c0cacccca803db48502c7bd461d04cb6b0Ben Chan  vector<pair<off_t, off_t>> ranges;
10913fd5d30433509859bfdcc0b650e242981410c6a7Andrew de los Reyes  ranges.push_back(make_pair(0, 24));
10929bedeb51f80c9547269eef6c2ec09596033bb818Gilad Arnold  MultiTest(this->test_.NewLargeFetcher(),
1093c1c17b4ed6a3896b6343e737fd89682fa0c8436bAlex Deymo            this->test_.fake_hardware(),
1094b6c562adec6e9491712f156f8fd50e2b807ff302Gilad Arnold            this->test_.BigUrl(server->GetPort()),
10953fd5d30433509859bfdcc0b650e242981410c6a7Andrew de los Reyes            ranges,
10963fd5d30433509859bfdcc0b650e242981410c6a7Andrew de los Reyes            "abcdefghijabcdefghijabcd",
10973fd5d30433509859bfdcc0b650e242981410c6a7Andrew de los Reyes            24,
1098e4ad2508de4d69d7a90d3ce441efe2c82c55bd1dGilad Arnold            kHttpResponsePartialContent);
10993fd5d30433509859bfdcc0b650e242981410c6a7Andrew de los Reyes}
11003fd5d30433509859bfdcc0b650e242981410c6a7Andrew de los Reyes
11013fd5d30433509859bfdcc0b650e242981410c6a7Andrew de los ReyesTYPED_TEST(HttpFetcherTest, MultiHttpFetcherMultiEndTest) {
11029bedeb51f80c9547269eef6c2ec09596033bb818Gilad Arnold  if (!this->test_.IsMulti())
11033fd5d30433509859bfdcc0b650e242981410c6a7Andrew de los Reyes    return;
11049bedeb51f80c9547269eef6c2ec09596033bb818Gilad Arnold
110502f7c1dee242f490143791dbb73fa23fa3007cfaBen Chan  unique_ptr<HttpServer> server(this->test_.CreateServer());
11069bedeb51f80c9547269eef6c2ec09596033bb818Gilad Arnold  ASSERT_TRUE(server->started_);
11073fd5d30433509859bfdcc0b650e242981410c6a7Andrew de los Reyes
1108f9cb98c0cacccca803db48502c7bd461d04cb6b0Ben Chan  vector<pair<off_t, off_t>> ranges;
1109e4ad2508de4d69d7a90d3ce441efe2c82c55bd1dGilad Arnold  ranges.push_back(make_pair(kBigLength - 2, 0));
1110e4ad2508de4d69d7a90d3ce441efe2c82c55bd1dGilad Arnold  ranges.push_back(make_pair(kBigLength - 3, 0));
11119bedeb51f80c9547269eef6c2ec09596033bb818Gilad Arnold  MultiTest(this->test_.NewLargeFetcher(),
1112c1c17b4ed6a3896b6343e737fd89682fa0c8436bAlex Deymo            this->test_.fake_hardware(),
1113b6c562adec6e9491712f156f8fd50e2b807ff302Gilad Arnold            this->test_.BigUrl(server->GetPort()),
11143fd5d30433509859bfdcc0b650e242981410c6a7Andrew de los Reyes            ranges,
11153fd5d30433509859bfdcc0b650e242981410c6a7Andrew de los Reyes            "ijhij",
11163fd5d30433509859bfdcc0b650e242981410c6a7Andrew de los Reyes            5,
11179bedeb51f80c9547269eef6c2ec09596033bb818Gilad Arnold            kHttpResponsePartialContent);
11183fd5d30433509859bfdcc0b650e242981410c6a7Andrew de los Reyes}
11193fd5d30433509859bfdcc0b650e242981410c6a7Andrew de los Reyes
11203fd5d30433509859bfdcc0b650e242981410c6a7Andrew de los ReyesTYPED_TEST(HttpFetcherTest, MultiHttpFetcherInsufficientTest) {
11219bedeb51f80c9547269eef6c2ec09596033bb818Gilad Arnold  if (!this->test_.IsMulti())
11223fd5d30433509859bfdcc0b650e242981410c6a7Andrew de los Reyes    return;
11239bedeb51f80c9547269eef6c2ec09596033bb818Gilad Arnold
112402f7c1dee242f490143791dbb73fa23fa3007cfaBen Chan  unique_ptr<HttpServer> server(this->test_.CreateServer());
11259bedeb51f80c9547269eef6c2ec09596033bb818Gilad Arnold  ASSERT_TRUE(server->started_);
11263fd5d30433509859bfdcc0b650e242981410c6a7Andrew de los Reyes
1127f9cb98c0cacccca803db48502c7bd461d04cb6b0Ben Chan  vector<pair<off_t, off_t>> ranges;
11289bedeb51f80c9547269eef6c2ec09596033bb818Gilad Arnold  ranges.push_back(make_pair(kBigLength - 2, 4));
11293fd5d30433509859bfdcc0b650e242981410c6a7Andrew de los Reyes  for (int i = 0; i < 2; ++i) {
1130819fef2e0fa08984cf31e848e704442c500ea4f9Andrew de los Reyes    LOG(INFO) << "i = " << i;
11319bedeb51f80c9547269eef6c2ec09596033bb818Gilad Arnold    MultiTest(this->test_.NewLargeFetcher(),
1132c1c17b4ed6a3896b6343e737fd89682fa0c8436bAlex Deymo              this->test_.fake_hardware(),
1133b6c562adec6e9491712f156f8fd50e2b807ff302Gilad Arnold              this->test_.BigUrl(server->GetPort()),
11343fd5d30433509859bfdcc0b650e242981410c6a7Andrew de los Reyes              ranges,
11353fd5d30433509859bfdcc0b650e242981410c6a7Andrew de los Reyes              "ij",
11363fd5d30433509859bfdcc0b650e242981410c6a7Andrew de los Reyes              2,
11379bedeb51f80c9547269eef6c2ec09596033bb818Gilad Arnold              kHttpResponseUndefined);
11383fd5d30433509859bfdcc0b650e242981410c6a7Andrew de los Reyes    ranges.push_back(make_pair(0, 5));
11393fd5d30433509859bfdcc0b650e242981410c6a7Andrew de los Reyes  }
11403fd5d30433509859bfdcc0b650e242981410c6a7Andrew de los Reyes}
11413fd5d30433509859bfdcc0b650e242981410c6a7Andrew de los Reyes
11429bedeb51f80c9547269eef6c2ec09596033bb818Gilad Arnold// Issue #18143: when a fetch of a secondary chunk out of a chain, then it
11439bedeb51f80c9547269eef6c2ec09596033bb818Gilad Arnold// should retry with other proxies listed before giving up.
11449bedeb51f80c9547269eef6c2ec09596033bb818Gilad Arnold//
11459bedeb51f80c9547269eef6c2ec09596033bb818Gilad Arnold// (1) successful recovery: The offset fetch will fail twice but succeed with
11469bedeb51f80c9547269eef6c2ec09596033bb818Gilad Arnold// the third proxy.
11479bedeb51f80c9547269eef6c2ec09596033bb818Gilad ArnoldTYPED_TEST(HttpFetcherTest, MultiHttpFetcherErrorIfOffsetRecoverableTest) {
11489bedeb51f80c9547269eef6c2ec09596033bb818Gilad Arnold  if (!this->test_.IsMulti())
11499bedeb51f80c9547269eef6c2ec09596033bb818Gilad Arnold    return;
11509bedeb51f80c9547269eef6c2ec09596033bb818Gilad Arnold
115102f7c1dee242f490143791dbb73fa23fa3007cfaBen Chan  unique_ptr<HttpServer> server(this->test_.CreateServer());
11529bedeb51f80c9547269eef6c2ec09596033bb818Gilad Arnold  ASSERT_TRUE(server->started_);
11539bedeb51f80c9547269eef6c2ec09596033bb818Gilad Arnold
1154f9cb98c0cacccca803db48502c7bd461d04cb6b0Ben Chan  vector<pair<off_t, off_t>> ranges;
11559bedeb51f80c9547269eef6c2ec09596033bb818Gilad Arnold  ranges.push_back(make_pair(0, 25));
1156e4ad2508de4d69d7a90d3ce441efe2c82c55bd1dGilad Arnold  ranges.push_back(make_pair(99, 0));
11579bedeb51f80c9547269eef6c2ec09596033bb818Gilad Arnold  MultiTest(this->test_.NewLargeFetcher(3),
1158c1c17b4ed6a3896b6343e737fd89682fa0c8436bAlex Deymo            this->test_.fake_hardware(),
1159b6c562adec6e9491712f156f8fd50e2b807ff302Gilad Arnold            LocalServerUrlForPath(server->GetPort(),
1160b6c562adec6e9491712f156f8fd50e2b807ff302Gilad Arnold                                  base::StringPrintf("/error-if-offset/%d/2",
11619bedeb51f80c9547269eef6c2ec09596033bb818Gilad Arnold                                                     kBigLength)),
11629bedeb51f80c9547269eef6c2ec09596033bb818Gilad Arnold            ranges,
11639bedeb51f80c9547269eef6c2ec09596033bb818Gilad Arnold            "abcdefghijabcdefghijabcdejabcdefghijabcdef",
11649bedeb51f80c9547269eef6c2ec09596033bb818Gilad Arnold            kBigLength - (99 - 25),
11659bedeb51f80c9547269eef6c2ec09596033bb818Gilad Arnold            kHttpResponsePartialContent);
11669bedeb51f80c9547269eef6c2ec09596033bb818Gilad Arnold}
11679bedeb51f80c9547269eef6c2ec09596033bb818Gilad Arnold
11689bedeb51f80c9547269eef6c2ec09596033bb818Gilad Arnold// (2) unsuccessful recovery: The offset fetch will fail repeatedly.  The
11699bedeb51f80c9547269eef6c2ec09596033bb818Gilad Arnold// fetcher will signal a (failed) completed transfer to the delegate.
11709bedeb51f80c9547269eef6c2ec09596033bb818Gilad ArnoldTYPED_TEST(HttpFetcherTest, MultiHttpFetcherErrorIfOffsetUnrecoverableTest) {
11719bedeb51f80c9547269eef6c2ec09596033bb818Gilad Arnold  if (!this->test_.IsMulti())
11729bedeb51f80c9547269eef6c2ec09596033bb818Gilad Arnold    return;
11739bedeb51f80c9547269eef6c2ec09596033bb818Gilad Arnold
117402f7c1dee242f490143791dbb73fa23fa3007cfaBen Chan  unique_ptr<HttpServer> server(this->test_.CreateServer());
11759bedeb51f80c9547269eef6c2ec09596033bb818Gilad Arnold  ASSERT_TRUE(server->started_);
11769bedeb51f80c9547269eef6c2ec09596033bb818Gilad Arnold
1177f9cb98c0cacccca803db48502c7bd461d04cb6b0Ben Chan  vector<pair<off_t, off_t>> ranges;
11789bedeb51f80c9547269eef6c2ec09596033bb818Gilad Arnold  ranges.push_back(make_pair(0, 25));
1179e4ad2508de4d69d7a90d3ce441efe2c82c55bd1dGilad Arnold  ranges.push_back(make_pair(99, 0));
11809bedeb51f80c9547269eef6c2ec09596033bb818Gilad Arnold  MultiTest(this->test_.NewLargeFetcher(2),
1181c1c17b4ed6a3896b6343e737fd89682fa0c8436bAlex Deymo            this->test_.fake_hardware(),
1182b6c562adec6e9491712f156f8fd50e2b807ff302Gilad Arnold            LocalServerUrlForPath(server->GetPort(),
1183b6c562adec6e9491712f156f8fd50e2b807ff302Gilad Arnold                                  base::StringPrintf("/error-if-offset/%d/3",
11849bedeb51f80c9547269eef6c2ec09596033bb818Gilad Arnold                                                     kBigLength)),
11859bedeb51f80c9547269eef6c2ec09596033bb818Gilad Arnold            ranges,
11869bedeb51f80c9547269eef6c2ec09596033bb818Gilad Arnold            "abcdefghijabcdefghijabcde",  // only received the first chunk
11879bedeb51f80c9547269eef6c2ec09596033bb818Gilad Arnold            25,
11889bedeb51f80c9547269eef6c2ec09596033bb818Gilad Arnold            kHttpResponseUndefined);
11899bedeb51f80c9547269eef6c2ec09596033bb818Gilad Arnold}
11909bedeb51f80c9547269eef6c2ec09596033bb818Gilad Arnold
11919bedeb51f80c9547269eef6c2ec09596033bb818Gilad Arnold
11929bedeb51f80c9547269eef6c2ec09596033bb818Gilad Arnold
1193d57d1474a7bb152adf10d8c31d7ef6d40d27f7ccAndrew de los Reyesnamespace {
1194fc7a0cec794ab43e66b6781ddb7f498b0ce257b9Darin Petkovclass BlockedTransferTestDelegate : public HttpFetcherDelegate {
1195d57d1474a7bb152adf10d8c31d7ef6d40d27f7ccAndrew de los Reyes public:
1196610277efc6f7e5239158dfa4bb3b1021804326e0Alex Deymo  void ReceivedBytes(HttpFetcher* fetcher,
1197f68bbbc952aa9a71898e4939b5f36187fa564a50Alex Vakulenko                     const void* bytes, size_t length) override {
1198d57d1474a7bb152adf10d8c31d7ef6d40d27f7ccAndrew de los Reyes    ADD_FAILURE();
1199d57d1474a7bb152adf10d8c31d7ef6d40d27f7ccAndrew de los Reyes  }
1200610277efc6f7e5239158dfa4bb3b1021804326e0Alex Deymo  void TransferComplete(HttpFetcher* fetcher, bool successful) override {
1201d57d1474a7bb152adf10d8c31d7ef6d40d27f7ccAndrew de los Reyes    EXPECT_FALSE(successful);
120260ca1a7bca7cc804ec80b510483081ef894de4cdAlex Deymo    MessageLoop::current()->BreakLoop();
1203d57d1474a7bb152adf10d8c31d7ef6d40d27f7ccAndrew de los Reyes  }
1204610277efc6f7e5239158dfa4bb3b1021804326e0Alex Deymo  void TransferTerminated(HttpFetcher* fetcher) override {
12059ce452b6acd95899e9adb17c2935012625163dc6Darin Petkov    ADD_FAILURE();
12069ce452b6acd95899e9adb17c2935012625163dc6Darin Petkov  }
1207d57d1474a7bb152adf10d8c31d7ef6d40d27f7ccAndrew de los Reyes};
1208d57d1474a7bb152adf10d8c31d7ef6d40d27f7ccAndrew de los Reyes
120960ca1a7bca7cc804ec80b510483081ef894de4cdAlex Deymovoid BlockedTransferTestHelper(AnyHttpFetcherTest* fetcher_test,
121060ca1a7bca7cc804ec80b510483081ef894de4cdAlex Deymo                               bool is_official_build) {
121160ca1a7bca7cc804ec80b510483081ef894de4cdAlex Deymo  if (fetcher_test->IsMock() || fetcher_test->IsMulti())
121260ca1a7bca7cc804ec80b510483081ef894de4cdAlex Deymo    return;
121360ca1a7bca7cc804ec80b510483081ef894de4cdAlex Deymo
121460ca1a7bca7cc804ec80b510483081ef894de4cdAlex Deymo  unique_ptr<HttpServer> server(fetcher_test->CreateServer());
121560ca1a7bca7cc804ec80b510483081ef894de4cdAlex Deymo  ASSERT_TRUE(server->started_);
121660ca1a7bca7cc804ec80b510483081ef894de4cdAlex Deymo
121760ca1a7bca7cc804ec80b510483081ef894de4cdAlex Deymo  BlockedTransferTestDelegate delegate;
121860ca1a7bca7cc804ec80b510483081ef894de4cdAlex Deymo  unique_ptr<HttpFetcher> fetcher(fetcher_test->NewLargeFetcher());
121960ca1a7bca7cc804ec80b510483081ef894de4cdAlex Deymo  LOG(INFO) << "is_official_build: " << is_official_build;
122060ca1a7bca7cc804ec80b510483081ef894de4cdAlex Deymo  // NewLargeFetcher creates the HttpFetcher* with a FakeSystemState.
1221c1c17b4ed6a3896b6343e737fd89682fa0c8436bAlex Deymo  fetcher_test->fake_hardware()->SetIsOfficialBuild(is_official_build);
122260ca1a7bca7cc804ec80b510483081ef894de4cdAlex Deymo  fetcher->set_delegate(&delegate);
122360ca1a7bca7cc804ec80b510483081ef894de4cdAlex Deymo
122460ca1a7bca7cc804ec80b510483081ef894de4cdAlex Deymo  MessageLoop::current()->PostTask(FROM_HERE, base::Bind(
122560ca1a7bca7cc804ec80b510483081ef894de4cdAlex Deymo      StartTransfer,
122660ca1a7bca7cc804ec80b510483081ef894de4cdAlex Deymo      fetcher.get(),
122760ca1a7bca7cc804ec80b510483081ef894de4cdAlex Deymo      LocalServerUrlForPath(server->GetPort(),
122860ca1a7bca7cc804ec80b510483081ef894de4cdAlex Deymo                            fetcher_test->SmallUrl(server->GetPort()))));
122960ca1a7bca7cc804ec80b510483081ef894de4cdAlex Deymo  MessageLoop::current()->Run();
123060ca1a7bca7cc804ec80b510483081ef894de4cdAlex Deymo}
1231d57d1474a7bb152adf10d8c31d7ef6d40d27f7ccAndrew de los Reyes}  // namespace
1232d57d1474a7bb152adf10d8c31d7ef6d40d27f7ccAndrew de los Reyes
1233fc7a0cec794ab43e66b6781ddb7f498b0ce257b9Darin PetkovTYPED_TEST(HttpFetcherTest, BlockedTransferTest) {
123460ca1a7bca7cc804ec80b510483081ef894de4cdAlex Deymo  BlockedTransferTestHelper(&this->test_, false);
123560ca1a7bca7cc804ec80b510483081ef894de4cdAlex Deymo}
1236d57d1474a7bb152adf10d8c31d7ef6d40d27f7ccAndrew de los Reyes
123760ca1a7bca7cc804ec80b510483081ef894de4cdAlex DeymoTYPED_TEST(HttpFetcherTest, BlockedTransferOfficialBuildTest) {
123860ca1a7bca7cc804ec80b510483081ef894de4cdAlex Deymo  BlockedTransferTestHelper(&this->test_, true);
1239d57d1474a7bb152adf10d8c31d7ef6d40d27f7ccAndrew de los Reyes}
1240d57d1474a7bb152adf10d8c31d7ef6d40d27f7ccAndrew de los Reyes
124149fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com}  // namespace chromeos_update_engine
1242