| Alex Deymo | aea4c1c | 2015-08-19 20:24:43 -0700 | [diff] [blame] | 1 | // | 
 | 2 | // Copyright (C) 2012 The Android Open Source Project | 
 | 3 | // | 
 | 4 | // Licensed under the Apache License, Version 2.0 (the "License"); | 
 | 5 | // you may not use this file except in compliance with the License. | 
 | 6 | // You may obtain a copy of the License at | 
 | 7 | // | 
 | 8 | //      http://www.apache.org/licenses/LICENSE-2.0 | 
 | 9 | // | 
 | 10 | // Unless required by applicable law or agreed to in writing, software | 
 | 11 | // distributed under the License is distributed on an "AS IS" BASIS, | 
 | 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 
 | 13 | // See the License for the specific language governing permissions and | 
 | 14 | // limitations under the License. | 
 | 15 | // | 
| rspangler@google.com | 49fdf18 | 2009-10-10 00:57:34 +0000 | [diff] [blame] | 16 |  | 
| Gilad Arnold | b6c562a | 2013-07-01 02:19:26 -0700 | [diff] [blame] | 17 | #include <netinet/in.h> | 
 | 18 | #include <netinet/ip.h> | 
 | 19 | #include <sys/socket.h> | 
| rspangler@google.com | 49fdf18 | 2009-10-10 00:57:34 +0000 | [diff] [blame] | 20 | #include <unistd.h> | 
| Darin Petkov | 41c2fcf | 2010-08-25 13:14:48 -0700 | [diff] [blame] | 21 |  | 
| Tao Bao | 642b32b | 2019-01-02 15:33:42 -0800 | [diff] [blame] | 22 | #include <algorithm> | 
| Daniel Zheng | 3e881aa | 2022-09-07 22:10:29 +0000 | [diff] [blame] | 23 | #include <deque> | 
| Ben Chan | 02f7c1d | 2014-10-18 15:18:02 -0700 | [diff] [blame] | 24 | #include <memory> | 
| adlr@google.com | c98a7ed | 2009-12-04 18:54:03 +0000 | [diff] [blame] | 25 | #include <string> | 
| Andrew de los Reyes | 3fd5d30 | 2010-10-07 20:07:18 -0700 | [diff] [blame] | 26 | #include <utility> | 
| adlr@google.com | c98a7ed | 2009-12-04 18:54:03 +0000 | [diff] [blame] | 27 | #include <vector> | 
| Darin Petkov | 41c2fcf | 2010-08-25 13:14:48 -0700 | [diff] [blame] | 28 |  | 
| Alex Deymo | 706a5ab | 2015-11-23 17:48:30 -0300 | [diff] [blame] | 29 | #include <base/bind.h> | 
| Alex Deymo | 60ca1a7 | 2015-06-18 18:19:15 -0700 | [diff] [blame] | 30 | #include <base/location.h> | 
| Andrew de los Reyes | 4516810 | 2010-11-22 11:13:50 -0800 | [diff] [blame] | 31 | #include <base/logging.h> | 
| Qijiang Fan | b0b6cc2 | 2020-10-15 21:54:11 +0900 | [diff] [blame] | 32 | #if BASE_VER < 780000  // Android | 
| Alex Deymo | 535f3b7 | 2015-08-07 10:51:32 -0700 | [diff] [blame] | 33 | #include <base/message_loop/message_loop.h> | 
| Qijiang Fan | b0b6cc2 | 2020-10-15 21:54:11 +0900 | [diff] [blame] | 34 | #endif  // BASE_VER < 780000 | 
| hscham | 00b6aa2 | 2020-02-20 12:32:06 +0900 | [diff] [blame] | 35 | #include <base/stl_util.h> | 
| Alex Deymo | 535f3b7 | 2015-08-07 10:51:32 -0700 | [diff] [blame] | 36 | #include <base/strings/string_number_conversions.h> | 
| Alex Vakulenko | 75039d7 | 2014-03-25 12:36:28 -0700 | [diff] [blame] | 37 | #include <base/strings/string_util.h> | 
 | 38 | #include <base/strings/stringprintf.h> | 
| Qijiang Fan | b0b6cc2 | 2020-10-15 21:54:11 +0900 | [diff] [blame] | 39 | #if BASE_VER >= 780000  // CrOS | 
 | 40 | #include <base/task/single_thread_task_executor.h> | 
 | 41 | #endif  // BASE_VER >= 780000 | 
| Alex Vakulenko | 75039d7 | 2014-03-25 12:36:28 -0700 | [diff] [blame] | 42 | #include <base/time/time.h> | 
| Alex Vakulenko | 3f39d5c | 2015-10-13 09:27:13 -0700 | [diff] [blame] | 43 | #include <brillo/message_loops/base_message_loop.h> | 
 | 44 | #include <brillo/message_loops/message_loop.h> | 
 | 45 | #include <brillo/message_loops/message_loop_utils.h> | 
| Amin Hassani | 4bd46b3 | 2020-09-15 15:30:09 -0700 | [diff] [blame] | 46 | #ifdef __CHROMEOS__ | 
 | 47 | #include <brillo/process/process.h> | 
 | 48 | #else | 
| Alex Vakulenko | 3f39d5c | 2015-10-13 09:27:13 -0700 | [diff] [blame] | 49 | #include <brillo/process.h> | 
| Amin Hassani | 4bd46b3 | 2020-09-15 15:30:09 -0700 | [diff] [blame] | 50 | #endif  // __CHROMEOS__ | 
| Alex Vakulenko | 3f39d5c | 2015-10-13 09:27:13 -0700 | [diff] [blame] | 51 | #include <brillo/streams/file_stream.h> | 
 | 52 | #include <brillo/streams/stream.h> | 
| Kelvin Zhang | c7a1d1f | 2022-07-29 13:36:29 -0700 | [diff] [blame] | 53 | #include <gmock/gmock.h> | 
| Daniel Zheng | 3e881aa | 2022-09-07 22:10:29 +0000 | [diff] [blame] | 54 | #include <gtest/gtest.h> | 
| Andrew de los Reyes | 4516810 | 2010-11-22 11:13:50 -0800 | [diff] [blame] | 55 |  | 
| Alex Deymo | c1c17b4 | 2015-11-23 03:53:15 -0300 | [diff] [blame] | 56 | #include "update_engine/common/fake_hardware.h" | 
| Alex Deymo | 2c131bb | 2016-05-26 16:43:13 -0700 | [diff] [blame] | 57 | #include "update_engine/common/file_fetcher.h" | 
| Alex Deymo | 39910dc | 2015-11-09 17:04:30 -0800 | [diff] [blame] | 58 | #include "update_engine/common/http_common.h" | 
| Alex Deymo | 39910dc | 2015-11-09 17:04:30 -0800 | [diff] [blame] | 59 | #include "update_engine/common/mock_http_fetcher.h" | 
 | 60 | #include "update_engine/common/multi_range_http_fetcher.h" | 
 | 61 | #include "update_engine/common/test_utils.h" | 
 | 62 | #include "update_engine/common/utils.h" | 
| Alex Deymo | 14c0da8 | 2016-07-20 16:45:45 -0700 | [diff] [blame] | 63 | #include "update_engine/libcurl_http_fetcher.h" | 
| rspangler@google.com | 49fdf18 | 2009-10-10 00:57:34 +0000 | [diff] [blame] | 64 |  | 
| Alex Vakulenko | 3f39d5c | 2015-10-13 09:27:13 -0700 | [diff] [blame] | 65 | using brillo::MessageLoop; | 
| Andrew de los Reyes | 3fd5d30 | 2010-10-07 20:07:18 -0700 | [diff] [blame] | 66 | using std::make_pair; | 
| Andrew de los Reyes | 819fef2 | 2010-12-17 11:33:58 -0800 | [diff] [blame] | 67 | using std::pair; | 
| adlr@google.com | c98a7ed | 2009-12-04 18:54:03 +0000 | [diff] [blame] | 68 | using std::string; | 
| Ben Chan | 02f7c1d | 2014-10-18 15:18:02 -0700 | [diff] [blame] | 69 | using std::unique_ptr; | 
| adlr@google.com | c98a7ed | 2009-12-04 18:54:03 +0000 | [diff] [blame] | 70 | using std::vector; | 
| Amin Hassani | b268959 | 2019-01-13 17:04:28 -0800 | [diff] [blame] | 71 | using testing::_; | 
| Alex Deymo | f285857 | 2016-02-25 11:20:13 -0800 | [diff] [blame] | 72 | using testing::DoAll; | 
 | 73 | using testing::Return; | 
 | 74 | using testing::SaveArg; | 
| adlr@google.com | c98a7ed | 2009-12-04 18:54:03 +0000 | [diff] [blame] | 75 |  | 
| Gilad Arnold | 9bedeb5 | 2011-11-17 16:19:57 -0800 | [diff] [blame] | 76 | namespace { | 
 | 77 |  | 
| Amin Hassani | b268959 | 2019-01-13 17:04:28 -0800 | [diff] [blame] | 78 | const int kBigLength = 100000; | 
 | 79 | const int kMediumLength = 1000; | 
| Gilad Arnold | 34bf1ee | 2012-02-09 16:16:02 -0800 | [diff] [blame] | 80 | const int kFlakyTruncateLength = 29000; | 
| Amin Hassani | b268959 | 2019-01-13 17:04:28 -0800 | [diff] [blame] | 81 | const int kFlakySleepEvery = 3; | 
 | 82 | const int kFlakySleepSecs = 10; | 
| Gilad Arnold | 9bedeb5 | 2011-11-17 16:19:57 -0800 | [diff] [blame] | 83 |  | 
 | 84 | }  // namespace | 
 | 85 |  | 
| rspangler@google.com | 49fdf18 | 2009-10-10 00:57:34 +0000 | [diff] [blame] | 86 | namespace chromeos_update_engine { | 
 | 87 |  | 
| Amin Hassani | b268959 | 2019-01-13 17:04:28 -0800 | [diff] [blame] | 88 | static const char* kUnusedUrl = "unused://unused"; | 
| Gilad Arnold | 9bedeb5 | 2011-11-17 16:19:57 -0800 | [diff] [blame] | 89 |  | 
| Amin Hassani | b268959 | 2019-01-13 17:04:28 -0800 | [diff] [blame] | 90 | static inline string LocalServerUrlForPath(in_port_t port, const string& path) { | 
| Alex Vakulenko | 75039d7 | 2014-03-25 12:36:28 -0700 | [diff] [blame] | 91 |   string port_str = (port ? base::StringPrintf(":%hu", port) : ""); | 
| Amin Hassani | b268959 | 2019-01-13 17:04:28 -0800 | [diff] [blame] | 92 |   return base::StringPrintf( | 
 | 93 |       "http://127.0.0.1%s%s", port_str.c_str(), path.c_str()); | 
| rspangler@google.com | 49fdf18 | 2009-10-10 00:57:34 +0000 | [diff] [blame] | 94 | } | 
 | 95 |  | 
| Gilad Arnold | 9bedeb5 | 2011-11-17 16:19:57 -0800 | [diff] [blame] | 96 | // | 
 | 97 | // Class hierarchy for HTTP server implementations. | 
 | 98 | // | 
 | 99 |  | 
| Kelvin Zhang | f0c73d4 | 2021-09-07 10:34:26 -0700 | [diff] [blame] | 100 | namespace { | 
 | 101 |  | 
| Gilad Arnold | 9bedeb5 | 2011-11-17 16:19:57 -0800 | [diff] [blame] | 102 | class HttpServer { | 
| rspangler@google.com | 49fdf18 | 2009-10-10 00:57:34 +0000 | [diff] [blame] | 103 |  public: | 
| Gilad Arnold | 9bedeb5 | 2011-11-17 16:19:57 -0800 | [diff] [blame] | 104 |   // This makes it an abstract class (dirty but works). | 
 | 105 |   virtual ~HttpServer() = 0; | 
 | 106 |  | 
| Amin Hassani | b268959 | 2019-01-13 17:04:28 -0800 | [diff] [blame] | 107 |   virtual in_port_t GetPort() const { return 0; } | 
| Gilad Arnold | b6c562a | 2013-07-01 02:19:26 -0700 | [diff] [blame] | 108 |  | 
| rspangler@google.com | 49fdf18 | 2009-10-10 00:57:34 +0000 | [diff] [blame] | 109 |   bool started_; | 
 | 110 | }; | 
 | 111 |  | 
| Gilad Arnold | 9bedeb5 | 2011-11-17 16:19:57 -0800 | [diff] [blame] | 112 | HttpServer::~HttpServer() {} | 
| rspangler@google.com | 49fdf18 | 2009-10-10 00:57:34 +0000 | [diff] [blame] | 113 |  | 
| Gilad Arnold | 9bedeb5 | 2011-11-17 16:19:57 -0800 | [diff] [blame] | 114 | class NullHttpServer : public HttpServer { | 
| rspangler@google.com | 49fdf18 | 2009-10-10 00:57:34 +0000 | [diff] [blame] | 115 |  public: | 
| Amin Hassani | b268959 | 2019-01-13 17:04:28 -0800 | [diff] [blame] | 116 |   NullHttpServer() { started_ = true; } | 
| rspangler@google.com | 49fdf18 | 2009-10-10 00:57:34 +0000 | [diff] [blame] | 117 | }; | 
 | 118 |  | 
| Gilad Arnold | 9bedeb5 | 2011-11-17 16:19:57 -0800 | [diff] [blame] | 119 | class PythonHttpServer : public HttpServer { | 
| rspangler@google.com | 49fdf18 | 2009-10-10 00:57:34 +0000 | [diff] [blame] | 120 |  public: | 
| Alex Deymo | 535f3b7 | 2015-08-07 10:51:32 -0700 | [diff] [blame] | 121 |   PythonHttpServer() : port_(0) { | 
| rspangler@google.com | 49fdf18 | 2009-10-10 00:57:34 +0000 | [diff] [blame] | 122 |     started_ = false; | 
| Gilad Arnold | b6c562a | 2013-07-01 02:19:26 -0700 | [diff] [blame] | 123 |  | 
 | 124 |     // Spawn the server process. | 
| Alex Vakulenko | 3f39d5c | 2015-10-13 09:27:13 -0700 | [diff] [blame] | 125 |     unique_ptr<brillo::Process> http_server(new brillo::ProcessImpl()); | 
| Sen Jiang | 260f03b | 2016-03-21 15:34:58 -0700 | [diff] [blame] | 126 |     http_server->AddArg(test_utils::GetBuildArtifactsPath("test_http_server")); | 
| Alex Deymo | 535f3b7 | 2015-08-07 10:51:32 -0700 | [diff] [blame] | 127 |     http_server->RedirectUsingPipe(STDOUT_FILENO, false); | 
 | 128 |  | 
 | 129 |     if (!http_server->Start()) { | 
 | 130 |       ADD_FAILURE() << "failed to spawn http server process"; | 
| rspangler@google.com | 49fdf18 | 2009-10-10 00:57:34 +0000 | [diff] [blame] | 131 |       return; | 
 | 132 |     } | 
| Alex Deymo | 535f3b7 | 2015-08-07 10:51:32 -0700 | [diff] [blame] | 133 |     LOG(INFO) << "started http server with pid " << http_server->pid(); | 
| Gilad Arnold | b6c562a | 2013-07-01 02:19:26 -0700 | [diff] [blame] | 134 |  | 
 | 135 |     // Wait for server to begin accepting connections, obtain its port. | 
| Alex Vakulenko | 3f39d5c | 2015-10-13 09:27:13 -0700 | [diff] [blame] | 136 |     brillo::StreamPtr stdout = brillo::FileStream::FromFileDescriptor( | 
| Alex Deymo | 535f3b7 | 2015-08-07 10:51:32 -0700 | [diff] [blame] | 137 |         http_server->GetPipe(STDOUT_FILENO), false /* own */, nullptr); | 
 | 138 |     if (!stdout) | 
 | 139 |       return; | 
 | 140 |  | 
 | 141 |     vector<char> buf(128); | 
 | 142 |     string line; | 
 | 143 |     while (line.find('\n') == string::npos) { | 
| Daniel Zheng | 3e881aa | 2022-09-07 22:10:29 +0000 | [diff] [blame] | 144 |       size_t read{}; | 
| Alex Deymo | 535f3b7 | 2015-08-07 10:51:32 -0700 | [diff] [blame] | 145 |       if (!stdout->ReadBlocking(buf.data(), buf.size(), &read, nullptr)) { | 
 | 146 |         ADD_FAILURE() << "error reading http server stdout"; | 
 | 147 |         return; | 
| Gilad Arnold | b6c562a | 2013-07-01 02:19:26 -0700 | [diff] [blame] | 148 |       } | 
| Alex Deymo | 535f3b7 | 2015-08-07 10:51:32 -0700 | [diff] [blame] | 149 |       line.append(buf.data(), read); | 
 | 150 |       if (read == 0) | 
 | 151 |         break; | 
 | 152 |     } | 
 | 153 |     // Parse the port from the output line. | 
 | 154 |     const size_t listening_msg_prefix_len = strlen(kServerListeningMsgPrefix); | 
 | 155 |     if (line.size() < listening_msg_prefix_len) { | 
 | 156 |       ADD_FAILURE() << "server output too short"; | 
| Gilad Arnold | b6c562a | 2013-07-01 02:19:26 -0700 | [diff] [blame] | 157 |       return; | 
 | 158 |     } | 
 | 159 |  | 
| Alex Deymo | 535f3b7 | 2015-08-07 10:51:32 -0700 | [diff] [blame] | 160 |     EXPECT_EQ(kServerListeningMsgPrefix, | 
 | 161 |               line.substr(0, listening_msg_prefix_len)); | 
 | 162 |     string port_str = line.substr(listening_msg_prefix_len); | 
 | 163 |     port_str.resize(port_str.find('\n')); | 
 | 164 |     EXPECT_TRUE(base::StringToUint(port_str, &port_)); | 
 | 165 |  | 
| Andrew de los Reyes | 3270f74 | 2010-07-15 22:28:14 -0700 | [diff] [blame] | 166 |     started_ = true; | 
| Gilad Arnold | b6c562a | 2013-07-01 02:19:26 -0700 | [diff] [blame] | 167 |     LOG(INFO) << "server running, listening on port " << port_; | 
| Alex Deymo | 535f3b7 | 2015-08-07 10:51:32 -0700 | [diff] [blame] | 168 |  | 
 | 169 |     // Any failure before this point will SIGKILL the test server if started | 
 | 170 |     // when the |http_server| goes out of scope. | 
 | 171 |     http_server_ = std::move(http_server); | 
| rspangler@google.com | 49fdf18 | 2009-10-10 00:57:34 +0000 | [diff] [blame] | 172 |   } | 
| Gilad Arnold | 9bedeb5 | 2011-11-17 16:19:57 -0800 | [diff] [blame] | 173 |  | 
| rspangler@google.com | 49fdf18 | 2009-10-10 00:57:34 +0000 | [diff] [blame] | 174 |   ~PythonHttpServer() { | 
| Gilad Arnold | b6c562a | 2013-07-01 02:19:26 -0700 | [diff] [blame] | 175 |     // If there's no process, do nothing. | 
| Alex Deymo | 535f3b7 | 2015-08-07 10:51:32 -0700 | [diff] [blame] | 176 |     if (!http_server_) | 
| rspangler@google.com | 49fdf18 | 2009-10-10 00:57:34 +0000 | [diff] [blame] | 177 |       return; | 
| Alex Deymo | 535f3b7 | 2015-08-07 10:51:32 -0700 | [diff] [blame] | 178 |     // Wait up to 10 seconds for the process to finish. Destroying the process | 
 | 179 |     // will kill it with a SIGKILL otherwise. | 
 | 180 |     http_server_->Kill(SIGTERM, 10); | 
| rspangler@google.com | 49fdf18 | 2009-10-10 00:57:34 +0000 | [diff] [blame] | 181 |   } | 
| Gilad Arnold | 9bedeb5 | 2011-11-17 16:19:57 -0800 | [diff] [blame] | 182 |  | 
| Amin Hassani | b268959 | 2019-01-13 17:04:28 -0800 | [diff] [blame] | 183 |   in_port_t GetPort() const override { return port_; } | 
| Gilad Arnold | b6c562a | 2013-07-01 02:19:26 -0700 | [diff] [blame] | 184 |  | 
 | 185 |  private: | 
| Gilad Arnold | b6c562a | 2013-07-01 02:19:26 -0700 | [diff] [blame] | 186 |   static const char* kServerListeningMsgPrefix; | 
 | 187 |  | 
| Alex Vakulenko | 3f39d5c | 2015-10-13 09:27:13 -0700 | [diff] [blame] | 188 |   unique_ptr<brillo::Process> http_server_; | 
| Alex Deymo | 535f3b7 | 2015-08-07 10:51:32 -0700 | [diff] [blame] | 189 |   unsigned int port_; | 
| rspangler@google.com | 49fdf18 | 2009-10-10 00:57:34 +0000 | [diff] [blame] | 190 | }; | 
 | 191 |  | 
| Gilad Arnold | b6c562a | 2013-07-01 02:19:26 -0700 | [diff] [blame] | 192 | const char* PythonHttpServer::kServerListeningMsgPrefix = "listening on port "; | 
 | 193 |  | 
| Gilad Arnold | 9bedeb5 | 2011-11-17 16:19:57 -0800 | [diff] [blame] | 194 | // | 
 | 195 | // Class hierarchy for HTTP fetcher test wrappers. | 
 | 196 | // | 
 | 197 |  | 
| Kelvin Zhang | f0c73d4 | 2021-09-07 10:34:26 -0700 | [diff] [blame] | 198 | class AnyHttpFetcherFactory { | 
| rspangler@google.com | 49fdf18 | 2009-10-10 00:57:34 +0000 | [diff] [blame] | 199 |  public: | 
| Kelvin Zhang | f0c73d4 | 2021-09-07 10:34:26 -0700 | [diff] [blame] | 200 |   AnyHttpFetcherFactory() {} | 
 | 201 |   virtual ~AnyHttpFetcherFactory() {} | 
| Jay Srinivasan | 4348879 | 2012-06-19 00:25:31 -0700 | [diff] [blame] | 202 |  | 
| Kelvin Zhang | c7a1d1f | 2022-07-29 13:36:29 -0700 | [diff] [blame] | 203 |   virtual HttpFetcher* NewLargeFetcher() = 0; | 
| Alex Deymo | f285857 | 2016-02-25 11:20:13 -0800 | [diff] [blame] | 204 |   HttpFetcher* NewLargeFetcher(size_t num_proxies) { | 
| Kelvin Zhang | c7a1d1f | 2022-07-29 13:36:29 -0700 | [diff] [blame] | 205 |     auto res = NewLargeFetcher(); | 
| Gilad Arnold | 9bedeb5 | 2011-11-17 16:19:57 -0800 | [diff] [blame] | 206 |  | 
| Kelvin Zhang | c7a1d1f | 2022-07-29 13:36:29 -0700 | [diff] [blame] | 207 |     res->SetProxies(std::deque<std::string>(num_proxies, kNoProxy)); | 
 | 208 |     return res; | 
| Gilad Arnold | 9bedeb5 | 2011-11-17 16:19:57 -0800 | [diff] [blame] | 209 |   } | 
 | 210 |  | 
| Daniel Zheng | 3e881aa | 2022-09-07 22:10:29 +0000 | [diff] [blame] | 211 |   virtual HttpFetcher* NewSmallFetcher() = 0; | 
| Gilad Arnold | 9bedeb5 | 2011-11-17 16:19:57 -0800 | [diff] [blame] | 212 |  | 
| Daniel Zheng | 3e881aa | 2022-09-07 22:10:29 +0000 | [diff] [blame] | 213 |   virtual string BigUrl(in_port_t port) const { return kUnusedUrl; } | 
 | 214 |   virtual string SmallUrl(in_port_t port) const { return kUnusedUrl; } | 
 | 215 |   virtual string ErrorUrl(in_port_t port) const { return kUnusedUrl; } | 
| Gilad Arnold | 9bedeb5 | 2011-11-17 16:19:57 -0800 | [diff] [blame] | 216 |  | 
| Daniel Zheng | 3e881aa | 2022-09-07 22:10:29 +0000 | [diff] [blame] | 217 |   virtual bool IsMock() const = 0; | 
 | 218 |   virtual bool IsMulti() const = 0; | 
 | 219 |   virtual bool IsHttpSupported() const = 0; | 
 | 220 |   virtual bool IsFileFetcher() const = 0; | 
| Gilad Arnold | 9bedeb5 | 2011-11-17 16:19:57 -0800 | [diff] [blame] | 221 |  | 
| Daniel Zheng | 3e881aa | 2022-09-07 22:10:29 +0000 | [diff] [blame] | 222 |   virtual void IgnoreServerAborting(HttpServer* server) const {} | 
| Gilad Arnold | 9bedeb5 | 2011-11-17 16:19:57 -0800 | [diff] [blame] | 223 |  | 
| Daniel Zheng | 3e881aa | 2022-09-07 22:10:29 +0000 | [diff] [blame] | 224 |   virtual HttpServer* CreateServer() = 0; | 
| Alex Deymo | c1c17b4 | 2015-11-23 03:53:15 -0300 | [diff] [blame] | 225 |  | 
| Daniel Zheng | 3e881aa | 2022-09-07 22:10:29 +0000 | [diff] [blame] | 226 |   FakeHardware* fake_hardware() { return &fake_hardware_; } | 
| Kelvin Zhang | c7a1d1f | 2022-07-29 13:36:29 -0700 | [diff] [blame] | 227 |  | 
| Daniel Zheng | 3e881aa | 2022-09-07 22:10:29 +0000 | [diff] [blame] | 228 |  protected: | 
 | 229 |   FakeHardware fake_hardware_; | 
| Gilad Arnold | 9bedeb5 | 2011-11-17 16:19:57 -0800 | [diff] [blame] | 230 | }; | 
 | 231 |  | 
| Kelvin Zhang | f0c73d4 | 2021-09-07 10:34:26 -0700 | [diff] [blame] | 232 | class MockHttpFetcherFactory : public AnyHttpFetcherFactory { | 
| Gilad Arnold | 9bedeb5 | 2011-11-17 16:19:57 -0800 | [diff] [blame] | 233 |  public: | 
 | 234 |   // Necessary to unhide the definition in the base class. | 
| Kelvin Zhang | f0c73d4 | 2021-09-07 10:34:26 -0700 | [diff] [blame] | 235 |   using AnyHttpFetcherFactory::NewLargeFetcher; | 
| Kelvin Zhang | c7a1d1f | 2022-07-29 13:36:29 -0700 | [diff] [blame] | 236 |   HttpFetcher* NewLargeFetcher() override { | 
| Alex Vakulenko | 3f39d5c | 2015-10-13 09:27:13 -0700 | [diff] [blame] | 237 |     brillo::Blob big_data(1000000); | 
| Kelvin Zhang | c7a1d1f | 2022-07-29 13:36:29 -0700 | [diff] [blame] | 238 |     return new MockHttpFetcher(big_data.data(), big_data.size()); | 
| Gilad Arnold | 9bedeb5 | 2011-11-17 16:19:57 -0800 | [diff] [blame] | 239 |   } | 
 | 240 |  | 
 | 241 |   // Necessary to unhide the definition in the base class. | 
| Kelvin Zhang | f0c73d4 | 2021-09-07 10:34:26 -0700 | [diff] [blame] | 242 |   using AnyHttpFetcherFactory::NewSmallFetcher; | 
| Kelvin Zhang | c7a1d1f | 2022-07-29 13:36:29 -0700 | [diff] [blame] | 243 |   HttpFetcher* NewSmallFetcher() override { | 
 | 244 |     return new MockHttpFetcher("x", 1); | 
| Gilad Arnold | 9bedeb5 | 2011-11-17 16:19:57 -0800 | [diff] [blame] | 245 |   } | 
 | 246 |  | 
| Alex Deymo | 610277e | 2014-11-11 21:18:11 -0800 | [diff] [blame] | 247 |   bool IsMock() const override { return true; } | 
 | 248 |   bool IsMulti() const override { return false; } | 
| Alex Deymo | 2c131bb | 2016-05-26 16:43:13 -0700 | [diff] [blame] | 249 |   bool IsHttpSupported() const override { return true; } | 
| Tao Bao | 642b32b | 2019-01-02 15:33:42 -0800 | [diff] [blame] | 250 |   bool IsFileFetcher() const override { return false; } | 
| Gilad Arnold | 9bedeb5 | 2011-11-17 16:19:57 -0800 | [diff] [blame] | 251 |  | 
| Amin Hassani | b268959 | 2019-01-13 17:04:28 -0800 | [diff] [blame] | 252 |   HttpServer* CreateServer() override { return new NullHttpServer; } | 
| Gilad Arnold | 9bedeb5 | 2011-11-17 16:19:57 -0800 | [diff] [blame] | 253 | }; | 
 | 254 |  | 
| Kelvin Zhang | f0c73d4 | 2021-09-07 10:34:26 -0700 | [diff] [blame] | 255 | class LibcurlHttpFetcherFactory : public AnyHttpFetcherFactory { | 
| Gilad Arnold | 9bedeb5 | 2011-11-17 16:19:57 -0800 | [diff] [blame] | 256 |  public: | 
 | 257 |   // Necessary to unhide the definition in the base class. | 
| Kelvin Zhang | f0c73d4 | 2021-09-07 10:34:26 -0700 | [diff] [blame] | 258 |   using AnyHttpFetcherFactory::NewLargeFetcher; | 
| Kelvin Zhang | c7a1d1f | 2022-07-29 13:36:29 -0700 | [diff] [blame] | 259 |   HttpFetcher* NewLargeFetcher() override { | 
 | 260 |     LibcurlHttpFetcher* ret = new LibcurlHttpFetcher(&fake_hardware_); | 
| Darin Petkov | b83371f | 2010-08-17 09:34:49 -0700 | [diff] [blame] | 261 |     // Speed up test execution. | 
 | 262 |     ret->set_idle_seconds(1); | 
 | 263 |     ret->set_retry_seconds(1); | 
| Alex Deymo | 706a5ab | 2015-11-23 17:48:30 -0300 | [diff] [blame] | 264 |     fake_hardware_.SetIsOfficialBuild(false); | 
| rspangler@google.com | 49fdf18 | 2009-10-10 00:57:34 +0000 | [diff] [blame] | 265 |     return ret; | 
 | 266 |   } | 
| Gilad Arnold | 9bedeb5 | 2011-11-17 16:19:57 -0800 | [diff] [blame] | 267 |  | 
 | 268 |   // Necessary to unhide the definition in the base class. | 
| Kelvin Zhang | f0c73d4 | 2021-09-07 10:34:26 -0700 | [diff] [blame] | 269 |   using AnyHttpFetcherFactory::NewSmallFetcher; | 
| Kelvin Zhang | c7a1d1f | 2022-07-29 13:36:29 -0700 | [diff] [blame] | 270 |  | 
 | 271 |   HttpFetcher* NewSmallFetcher() override { return NewLargeFetcher(); } | 
| Gilad Arnold | 9bedeb5 | 2011-11-17 16:19:57 -0800 | [diff] [blame] | 272 |  | 
| Alex Deymo | 610277e | 2014-11-11 21:18:11 -0800 | [diff] [blame] | 273 |   string BigUrl(in_port_t port) const override { | 
| Amin Hassani | b268959 | 2019-01-13 17:04:28 -0800 | [diff] [blame] | 274 |     return LocalServerUrlForPath( | 
 | 275 |         port, base::StringPrintf("/download/%d", kBigLength)); | 
| rspangler@google.com | 49fdf18 | 2009-10-10 00:57:34 +0000 | [diff] [blame] | 276 |   } | 
| Alex Deymo | 610277e | 2014-11-11 21:18:11 -0800 | [diff] [blame] | 277 |   string SmallUrl(in_port_t port) const override { | 
| Gilad Arnold | b6c562a | 2013-07-01 02:19:26 -0700 | [diff] [blame] | 278 |     return LocalServerUrlForPath(port, "/foo"); | 
| rspangler@google.com | 49fdf18 | 2009-10-10 00:57:34 +0000 | [diff] [blame] | 279 |   } | 
| Alex Deymo | 610277e | 2014-11-11 21:18:11 -0800 | [diff] [blame] | 280 |   string ErrorUrl(in_port_t port) const override { | 
| Gilad Arnold | b6c562a | 2013-07-01 02:19:26 -0700 | [diff] [blame] | 281 |     return LocalServerUrlForPath(port, "/error"); | 
| Gilad Arnold | 48085ba | 2011-11-16 09:36:08 -0800 | [diff] [blame] | 282 |   } | 
| Gilad Arnold | 9bedeb5 | 2011-11-17 16:19:57 -0800 | [diff] [blame] | 283 |  | 
| Alex Deymo | 610277e | 2014-11-11 21:18:11 -0800 | [diff] [blame] | 284 |   bool IsMock() const override { return false; } | 
 | 285 |   bool IsMulti() const override { return false; } | 
| Alex Deymo | 2c131bb | 2016-05-26 16:43:13 -0700 | [diff] [blame] | 286 |   bool IsHttpSupported() const override { return true; } | 
| Tao Bao | 642b32b | 2019-01-02 15:33:42 -0800 | [diff] [blame] | 287 |   bool IsFileFetcher() const override { return false; } | 
| Gilad Arnold | 9bedeb5 | 2011-11-17 16:19:57 -0800 | [diff] [blame] | 288 |  | 
| Alex Deymo | 610277e | 2014-11-11 21:18:11 -0800 | [diff] [blame] | 289 |   void IgnoreServerAborting(HttpServer* server) const override { | 
| Gilad Arnold | b6c562a | 2013-07-01 02:19:26 -0700 | [diff] [blame] | 290 |     // Nothing to do. | 
| Andrew de los Reyes | 08c4e27 | 2010-04-15 14:02:17 -0700 | [diff] [blame] | 291 |   } | 
| Gilad Arnold | 9bedeb5 | 2011-11-17 16:19:57 -0800 | [diff] [blame] | 292 |  | 
| Amin Hassani | b268959 | 2019-01-13 17:04:28 -0800 | [diff] [blame] | 293 |   HttpServer* CreateServer() override { return new PythonHttpServer; } | 
| rspangler@google.com | 49fdf18 | 2009-10-10 00:57:34 +0000 | [diff] [blame] | 294 | }; | 
 | 295 |  | 
| Kelvin Zhang | f0c73d4 | 2021-09-07 10:34:26 -0700 | [diff] [blame] | 296 | class MultiRangeHttpFetcherFactory : public LibcurlHttpFetcherFactory { | 
| Andrew de los Reyes | 3fd5d30 | 2010-10-07 20:07:18 -0700 | [diff] [blame] | 297 |  public: | 
| Gilad Arnold | 9bedeb5 | 2011-11-17 16:19:57 -0800 | [diff] [blame] | 298 |   // Necessary to unhide the definition in the base class. | 
| Kelvin Zhang | f0c73d4 | 2021-09-07 10:34:26 -0700 | [diff] [blame] | 299 |   using AnyHttpFetcherFactory::NewLargeFetcher; | 
| Kelvin Zhang | c7a1d1f | 2022-07-29 13:36:29 -0700 | [diff] [blame] | 300 |   HttpFetcher* NewLargeFetcher() override { | 
 | 301 |     MultiRangeHttpFetcher* ret = | 
 | 302 |         new MultiRangeHttpFetcher(new LibcurlHttpFetcher(&fake_hardware_)); | 
| Andrew de los Reyes | 819fef2 | 2010-12-17 11:33:58 -0800 | [diff] [blame] | 303 |     ret->ClearRanges(); | 
| Gilad Arnold | e4ad250 | 2011-12-29 17:08:54 -0800 | [diff] [blame] | 304 |     ret->AddRange(0); | 
| Andrew de los Reyes | 3fd5d30 | 2010-10-07 20:07:18 -0700 | [diff] [blame] | 305 |     // Speed up test execution. | 
 | 306 |     ret->set_idle_seconds(1); | 
 | 307 |     ret->set_retry_seconds(1); | 
| Alex Deymo | 706a5ab | 2015-11-23 17:48:30 -0300 | [diff] [blame] | 308 |     fake_hardware_.SetIsOfficialBuild(false); | 
| Andrew de los Reyes | 3fd5d30 | 2010-10-07 20:07:18 -0700 | [diff] [blame] | 309 |     return ret; | 
 | 310 |   } | 
| Gilad Arnold | 9bedeb5 | 2011-11-17 16:19:57 -0800 | [diff] [blame] | 311 |  | 
 | 312 |   // Necessary to unhide the definition in the base class. | 
| Kelvin Zhang | f0c73d4 | 2021-09-07 10:34:26 -0700 | [diff] [blame] | 313 |   using AnyHttpFetcherFactory::NewSmallFetcher; | 
| Kelvin Zhang | c7a1d1f | 2022-07-29 13:36:29 -0700 | [diff] [blame] | 314 |   HttpFetcher* NewSmallFetcher() override { return NewLargeFetcher(); } | 
| Gilad Arnold | 9bedeb5 | 2011-11-17 16:19:57 -0800 | [diff] [blame] | 315 |  | 
| Alex Deymo | 610277e | 2014-11-11 21:18:11 -0800 | [diff] [blame] | 316 |   bool IsMulti() const override { return true; } | 
| Andrew de los Reyes | 3fd5d30 | 2010-10-07 20:07:18 -0700 | [diff] [blame] | 317 | }; | 
 | 318 |  | 
| Kelvin Zhang | f0c73d4 | 2021-09-07 10:34:26 -0700 | [diff] [blame] | 319 | class FileFetcherFactory : public AnyHttpFetcherFactory { | 
| Alex Deymo | 2c131bb | 2016-05-26 16:43:13 -0700 | [diff] [blame] | 320 |  public: | 
 | 321 |   // Necessary to unhide the definition in the base class. | 
| Kelvin Zhang | f0c73d4 | 2021-09-07 10:34:26 -0700 | [diff] [blame] | 322 |   using AnyHttpFetcherFactory::NewLargeFetcher; | 
| Kelvin Zhang | c7a1d1f | 2022-07-29 13:36:29 -0700 | [diff] [blame] | 323 |   HttpFetcher* NewLargeFetcher() override { return new FileFetcher(); } | 
| Alex Deymo | 2c131bb | 2016-05-26 16:43:13 -0700 | [diff] [blame] | 324 |  | 
 | 325 |   // Necessary to unhide the definition in the base class. | 
| Kelvin Zhang | f0c73d4 | 2021-09-07 10:34:26 -0700 | [diff] [blame] | 326 |   using AnyHttpFetcherFactory::NewSmallFetcher; | 
| Kelvin Zhang | c7a1d1f | 2022-07-29 13:36:29 -0700 | [diff] [blame] | 327 |   HttpFetcher* NewSmallFetcher() override { return NewLargeFetcher(); } | 
| Alex Deymo | 2c131bb | 2016-05-26 16:43:13 -0700 | [diff] [blame] | 328 |  | 
 | 329 |   string BigUrl(in_port_t port) const override { | 
| Tao Bao | 642b32b | 2019-01-02 15:33:42 -0800 | [diff] [blame] | 330 |     static string big_contents = []() { | 
 | 331 |       string buf; | 
 | 332 |       buf.reserve(kBigLength); | 
 | 333 |       constexpr const char* kBigUrlContent = "abcdefghij"; | 
 | 334 |       for (size_t i = 0; i < kBigLength; i += strlen(kBigUrlContent)) { | 
 | 335 |         buf.append(kBigUrlContent, | 
 | 336 |                    std::min(kBigLength - i, strlen(kBigUrlContent))); | 
 | 337 |       } | 
 | 338 |       return buf; | 
 | 339 |     }(); | 
 | 340 |     test_utils::WriteFileString(temp_file_.path(), big_contents); | 
| Alex Deymo | 2c131bb | 2016-05-26 16:43:13 -0700 | [diff] [blame] | 341 |     return "file://" + temp_file_.path(); | 
 | 342 |   } | 
 | 343 |   string SmallUrl(in_port_t port) const override { | 
 | 344 |     test_utils::WriteFileString(temp_file_.path(), "small contents"); | 
 | 345 |     return "file://" + temp_file_.path(); | 
 | 346 |   } | 
 | 347 |   string ErrorUrl(in_port_t port) const override { | 
 | 348 |     return "file:///path/to/non-existing-file"; | 
 | 349 |   } | 
 | 350 |  | 
 | 351 |   bool IsMock() const override { return false; } | 
 | 352 |   bool IsMulti() const override { return false; } | 
 | 353 |   bool IsHttpSupported() const override { return false; } | 
| Tao Bao | 642b32b | 2019-01-02 15:33:42 -0800 | [diff] [blame] | 354 |   bool IsFileFetcher() const override { return true; } | 
| Alex Deymo | 2c131bb | 2016-05-26 16:43:13 -0700 | [diff] [blame] | 355 |  | 
 | 356 |   void IgnoreServerAborting(HttpServer* server) const override {} | 
 | 357 |  | 
 | 358 |   HttpServer* CreateServer() override { return new NullHttpServer; } | 
 | 359 |  | 
 | 360 |  private: | 
| Amin Hassani | ed03b44 | 2020-10-26 17:21:29 -0700 | [diff] [blame] | 361 |   ScopedTempFile temp_file_{"ue_file_fetcher.XXXXXX"}; | 
| Alex Deymo | 2c131bb | 2016-05-26 16:43:13 -0700 | [diff] [blame] | 362 | }; | 
| Gilad Arnold | 9bedeb5 | 2011-11-17 16:19:57 -0800 | [diff] [blame] | 363 |  | 
| Kelvin Zhang | f0c73d4 | 2021-09-07 10:34:26 -0700 | [diff] [blame] | 364 | class MultiRangeHttpFetcherOverFileFetcherFactory : public FileFetcherFactory { | 
| Tao Bao | 642b32b | 2019-01-02 15:33:42 -0800 | [diff] [blame] | 365 |  public: | 
 | 366 |   // Necessary to unhide the definition in the base class. | 
| Kelvin Zhang | f0c73d4 | 2021-09-07 10:34:26 -0700 | [diff] [blame] | 367 |   using AnyHttpFetcherFactory::NewLargeFetcher; | 
| Kelvin Zhang | c7a1d1f | 2022-07-29 13:36:29 -0700 | [diff] [blame] | 368 |   HttpFetcher* NewLargeFetcher() override { | 
| Tao Bao | 642b32b | 2019-01-02 15:33:42 -0800 | [diff] [blame] | 369 |     MultiRangeHttpFetcher* ret = new MultiRangeHttpFetcher(new FileFetcher()); | 
 | 370 |     ret->ClearRanges(); | 
 | 371 |     // FileFetcher doesn't support range with unspecified length. | 
 | 372 |     ret->AddRange(0, 1); | 
 | 373 |     // Speed up test execution. | 
 | 374 |     ret->set_idle_seconds(1); | 
 | 375 |     ret->set_retry_seconds(1); | 
 | 376 |     fake_hardware_.SetIsOfficialBuild(false); | 
 | 377 |     return ret; | 
 | 378 |   } | 
 | 379 |  | 
 | 380 |   // Necessary to unhide the definition in the base class. | 
| Kelvin Zhang | f0c73d4 | 2021-09-07 10:34:26 -0700 | [diff] [blame] | 381 |   using AnyHttpFetcherFactory::NewSmallFetcher; | 
| Kelvin Zhang | c7a1d1f | 2022-07-29 13:36:29 -0700 | [diff] [blame] | 382 |   HttpFetcher* NewSmallFetcher() override { return NewLargeFetcher(); } | 
| Tao Bao | 642b32b | 2019-01-02 15:33:42 -0800 | [diff] [blame] | 383 |  | 
 | 384 |   bool IsMulti() const override { return true; } | 
 | 385 | }; | 
 | 386 |  | 
| Gilad Arnold | 9bedeb5 | 2011-11-17 16:19:57 -0800 | [diff] [blame] | 387 | // | 
 | 388 | // Infrastructure for type tests of HTTP fetcher. | 
 | 389 | // See: http://code.google.com/p/googletest/wiki/AdvancedGuide#Typed_Tests | 
 | 390 | // | 
 | 391 |  | 
 | 392 | // Fixture class template. We use an explicit constraint to guarantee that it | 
 | 393 | // can only be instantiated with an AnyHttpFetcherTest type, see: | 
 | 394 | // http://www2.research.att.com/~bs/bs_faq2.html#constraints | 
 | 395 | template <typename T> | 
 | 396 | class HttpFetcherTest : public ::testing::Test { | 
 | 397 |  public: | 
| Qijiang Fan | b0b6cc2 | 2020-10-15 21:54:11 +0900 | [diff] [blame] | 398 | #if BASE_VER < 780000  // Android | 
| Alex Deymo | 535f3b7 | 2015-08-07 10:51:32 -0700 | [diff] [blame] | 399 |   base::MessageLoopForIO base_loop_; | 
| Alex Vakulenko | 3f39d5c | 2015-10-13 09:27:13 -0700 | [diff] [blame] | 400 |   brillo::BaseMessageLoop loop_{&base_loop_}; | 
| Qijiang Fan | b0b6cc2 | 2020-10-15 21:54:11 +0900 | [diff] [blame] | 401 | #else   // Chrome OS | 
 | 402 |   base::SingleThreadTaskExecutor base_loop_{base::MessagePumpType::IO}; | 
 | 403 |   brillo::BaseMessageLoop loop_{base_loop_.task_runner()}; | 
 | 404 | #endif  // BASE_VER < 780000 | 
| Alex Deymo | 60ca1a7 | 2015-06-18 18:19:15 -0700 | [diff] [blame] | 405 |  | 
| Gilad Arnold | 9bedeb5 | 2011-11-17 16:19:57 -0800 | [diff] [blame] | 406 |   T test_; | 
 | 407 |  | 
| Alex Deymo | 60ca1a7 | 2015-06-18 18:19:15 -0700 | [diff] [blame] | 408 |  protected: | 
| Amin Hassani | b268959 | 2019-01-13 17:04:28 -0800 | [diff] [blame] | 409 |   HttpFetcherTest() { loop_.SetAsCurrent(); } | 
| Alex Deymo | 60ca1a7 | 2015-06-18 18:19:15 -0700 | [diff] [blame] | 410 |  | 
 | 411 |   void TearDown() override { | 
| Alex Vakulenko | 3f39d5c | 2015-10-13 09:27:13 -0700 | [diff] [blame] | 412 |     EXPECT_EQ(0, brillo::MessageLoopRunMaxIterations(&loop_, 1)); | 
| Alex Deymo | 60ca1a7 | 2015-06-18 18:19:15 -0700 | [diff] [blame] | 413 |   } | 
 | 414 |  | 
| Gilad Arnold | 9bedeb5 | 2011-11-17 16:19:57 -0800 | [diff] [blame] | 415 |  private: | 
| Alex Deymo | 60ca1a7 | 2015-06-18 18:19:15 -0700 | [diff] [blame] | 416 |   static void TypeConstraint(T* a) { | 
| Kelvin Zhang | f0c73d4 | 2021-09-07 10:34:26 -0700 | [diff] [blame] | 417 |     AnyHttpFetcherFactory* b = a; | 
| Alex Vakulenko | d2779df | 2014-06-16 13:19:00 -0700 | [diff] [blame] | 418 |     if (b == 0)  // Silence compiler warning of unused variable. | 
| Yunlian Jiang | 2dac576 | 2013-04-12 09:53:09 -0700 | [diff] [blame] | 419 |       *b = a; | 
| Gilad Arnold | 9bedeb5 | 2011-11-17 16:19:57 -0800 | [diff] [blame] | 420 |   } | 
 | 421 | }; | 
 | 422 |  | 
 | 423 | // Test case types list. | 
| Kelvin Zhang | f0c73d4 | 2021-09-07 10:34:26 -0700 | [diff] [blame] | 424 | typedef ::testing::Types<LibcurlHttpFetcherFactory, | 
 | 425 |                          MockHttpFetcherFactory, | 
 | 426 |                          MultiRangeHttpFetcherFactory, | 
 | 427 |                          FileFetcherFactory, | 
 | 428 |                          MultiRangeHttpFetcherOverFileFetcherFactory> | 
| Alex Deymo | 2c131bb | 2016-05-26 16:43:13 -0700 | [diff] [blame] | 429 |     HttpFetcherTestTypes; | 
| rspangler@google.com | 49fdf18 | 2009-10-10 00:57:34 +0000 | [diff] [blame] | 430 | TYPED_TEST_CASE(HttpFetcherTest, HttpFetcherTestTypes); | 
 | 431 |  | 
| rspangler@google.com | 49fdf18 | 2009-10-10 00:57:34 +0000 | [diff] [blame] | 432 | class HttpFetcherTestDelegate : public HttpFetcherDelegate { | 
| adlr@google.com | c98a7ed | 2009-12-04 18:54:03 +0000 | [diff] [blame] | 433 |  public: | 
| Alex Deymo | fdd6dec | 2016-03-03 22:35:43 -0800 | [diff] [blame] | 434 |   HttpFetcherTestDelegate() = default; | 
| Gilad Arnold | 48085ba | 2011-11-16 09:36:08 -0800 | [diff] [blame] | 435 |  | 
| Amin Hassani | 0cd9d77 | 2018-07-31 23:55:43 -0700 | [diff] [blame] | 436 |   bool ReceivedBytes(HttpFetcher* /* fetcher */, | 
| Alex Deymo | fdd6dec | 2016-03-03 22:35:43 -0800 | [diff] [blame] | 437 |                      const void* bytes, | 
 | 438 |                      size_t length) override { | 
 | 439 |     data.append(reinterpret_cast<const char*>(bytes), length); | 
| Gilad Arnold | 48085ba | 2011-11-16 09:36:08 -0800 | [diff] [blame] | 440 |     // Update counters | 
 | 441 |     times_received_bytes_called_++; | 
| Amin Hassani | 0cd9d77 | 2018-07-31 23:55:43 -0700 | [diff] [blame] | 442 |     return true; | 
| rspangler@google.com | 49fdf18 | 2009-10-10 00:57:34 +0000 | [diff] [blame] | 443 |   } | 
| Gilad Arnold | 48085ba | 2011-11-16 09:36:08 -0800 | [diff] [blame] | 444 |  | 
| Alex Deymo | 610277e | 2014-11-11 21:18:11 -0800 | [diff] [blame] | 445 |   void TransferComplete(HttpFetcher* fetcher, bool successful) override { | 
| Gilad Arnold | 48085ba | 2011-11-16 09:36:08 -0800 | [diff] [blame] | 446 |     if (is_expect_error_) | 
| Gilad Arnold | 9bedeb5 | 2011-11-17 16:19:57 -0800 | [diff] [blame] | 447 |       EXPECT_EQ(kHttpResponseNotFound, fetcher->http_response_code()); | 
| Gilad Arnold | 48085ba | 2011-11-16 09:36:08 -0800 | [diff] [blame] | 448 |     else | 
| Gilad Arnold | 9bedeb5 | 2011-11-17 16:19:57 -0800 | [diff] [blame] | 449 |       EXPECT_EQ(kHttpResponseOk, fetcher->http_response_code()); | 
| Alex Deymo | 60ca1a7 | 2015-06-18 18:19:15 -0700 | [diff] [blame] | 450 |     MessageLoop::current()->BreakLoop(); | 
| Gilad Arnold | 48085ba | 2011-11-16 09:36:08 -0800 | [diff] [blame] | 451 |  | 
 | 452 |     // Update counter | 
 | 453 |     times_transfer_complete_called_++; | 
| rspangler@google.com | 49fdf18 | 2009-10-10 00:57:34 +0000 | [diff] [blame] | 454 |   } | 
| Gilad Arnold | 48085ba | 2011-11-16 09:36:08 -0800 | [diff] [blame] | 455 |  | 
| Alex Deymo | 610277e | 2014-11-11 21:18:11 -0800 | [diff] [blame] | 456 |   void TransferTerminated(HttpFetcher* fetcher) override { | 
| Gilad Arnold | 48085ba | 2011-11-16 09:36:08 -0800 | [diff] [blame] | 457 |     times_transfer_terminated_called_++; | 
| Alex Deymo | 2c131bb | 2016-05-26 16:43:13 -0700 | [diff] [blame] | 458 |     MessageLoop::current()->BreakLoop(); | 
| Darin Petkov | 9ce452b | 2010-11-17 14:33:28 -0800 | [diff] [blame] | 459 |   } | 
| Gilad Arnold | 48085ba | 2011-11-16 09:36:08 -0800 | [diff] [blame] | 460 |  | 
| Gilad Arnold | 48085ba | 2011-11-16 09:36:08 -0800 | [diff] [blame] | 461 |   // Are we expecting an error response? (default: no) | 
| Alex Deymo | fdd6dec | 2016-03-03 22:35:43 -0800 | [diff] [blame] | 462 |   bool is_expect_error_{false}; | 
| Gilad Arnold | 48085ba | 2011-11-16 09:36:08 -0800 | [diff] [blame] | 463 |  | 
 | 464 |   // Counters for callback invocations. | 
| Alex Deymo | fdd6dec | 2016-03-03 22:35:43 -0800 | [diff] [blame] | 465 |   int times_transfer_complete_called_{0}; | 
 | 466 |   int times_transfer_terminated_called_{0}; | 
 | 467 |   int times_received_bytes_called_{0}; | 
 | 468 |  | 
 | 469 |   // The received data bytes. | 
 | 470 |   string data; | 
| rspangler@google.com | 49fdf18 | 2009-10-10 00:57:34 +0000 | [diff] [blame] | 471 | }; | 
| adlr@google.com | c98a7ed | 2009-12-04 18:54:03 +0000 | [diff] [blame] | 472 |  | 
| Alex Deymo | 60ca1a7 | 2015-06-18 18:19:15 -0700 | [diff] [blame] | 473 | void StartTransfer(HttpFetcher* http_fetcher, const string& url) { | 
 | 474 |   http_fetcher->BeginTransfer(url); | 
| adlr@google.com | c98a7ed | 2009-12-04 18:54:03 +0000 | [diff] [blame] | 475 | } | 
| rspangler@google.com | 49fdf18 | 2009-10-10 00:57:34 +0000 | [diff] [blame] | 476 |  | 
 | 477 | TYPED_TEST(HttpFetcherTest, SimpleTest) { | 
| Alex Deymo | 60ca1a7 | 2015-06-18 18:19:15 -0700 | [diff] [blame] | 478 |   HttpFetcherTestDelegate delegate; | 
 | 479 |   unique_ptr<HttpFetcher> fetcher(this->test_.NewSmallFetcher()); | 
 | 480 |   fetcher->set_delegate(&delegate); | 
| rspangler@google.com | 49fdf18 | 2009-10-10 00:57:34 +0000 | [diff] [blame] | 481 |  | 
| Alex Deymo | 60ca1a7 | 2015-06-18 18:19:15 -0700 | [diff] [blame] | 482 |   unique_ptr<HttpServer> server(this->test_.CreateServer()); | 
 | 483 |   ASSERT_TRUE(server->started_); | 
| rspangler@google.com | 49fdf18 | 2009-10-10 00:57:34 +0000 | [diff] [blame] | 484 |  | 
| Amin Hassani | b268959 | 2019-01-13 17:04:28 -0800 | [diff] [blame] | 485 |   this->loop_.PostTask(FROM_HERE, | 
 | 486 |                        base::Bind(StartTransfer, | 
 | 487 |                                   fetcher.get(), | 
 | 488 |                                   this->test_.SmallUrl(server->GetPort()))); | 
| Alex Deymo | 60ca1a7 | 2015-06-18 18:19:15 -0700 | [diff] [blame] | 489 |   this->loop_.Run(); | 
| Alex Deymo | 71f6762 | 2017-02-03 21:30:24 -0800 | [diff] [blame] | 490 |   EXPECT_EQ(0, delegate.times_transfer_terminated_called_); | 
| rspangler@google.com | 49fdf18 | 2009-10-10 00:57:34 +0000 | [diff] [blame] | 491 | } | 
 | 492 |  | 
| Andrew de los Reyes | 3270f74 | 2010-07-15 22:28:14 -0700 | [diff] [blame] | 493 | TYPED_TEST(HttpFetcherTest, SimpleBigTest) { | 
| Alex Deymo | 60ca1a7 | 2015-06-18 18:19:15 -0700 | [diff] [blame] | 494 |   HttpFetcherTestDelegate delegate; | 
 | 495 |   unique_ptr<HttpFetcher> fetcher(this->test_.NewLargeFetcher()); | 
 | 496 |   fetcher->set_delegate(&delegate); | 
| Andrew de los Reyes | 3270f74 | 2010-07-15 22:28:14 -0700 | [diff] [blame] | 497 |  | 
| Alex Deymo | 60ca1a7 | 2015-06-18 18:19:15 -0700 | [diff] [blame] | 498 |   unique_ptr<HttpServer> server(this->test_.CreateServer()); | 
 | 499 |   ASSERT_TRUE(server->started_); | 
| Andrew de los Reyes | 3270f74 | 2010-07-15 22:28:14 -0700 | [diff] [blame] | 500 |  | 
| Amin Hassani | b268959 | 2019-01-13 17:04:28 -0800 | [diff] [blame] | 501 |   this->loop_.PostTask( | 
 | 502 |       FROM_HERE, | 
 | 503 |       base::Bind( | 
 | 504 |           StartTransfer, fetcher.get(), this->test_.BigUrl(server->GetPort()))); | 
| Alex Deymo | 60ca1a7 | 2015-06-18 18:19:15 -0700 | [diff] [blame] | 505 |   this->loop_.Run(); | 
| Alex Deymo | 71f6762 | 2017-02-03 21:30:24 -0800 | [diff] [blame] | 506 |   EXPECT_EQ(0, delegate.times_transfer_terminated_called_); | 
| Andrew de los Reyes | 3270f74 | 2010-07-15 22:28:14 -0700 | [diff] [blame] | 507 | } | 
 | 508 |  | 
| Gilad Arnold | 48085ba | 2011-11-16 09:36:08 -0800 | [diff] [blame] | 509 | // Issue #9648: when server returns an error HTTP response, the fetcher needs to | 
 | 510 | // terminate transfer prematurely, rather than try to process the error payload. | 
 | 511 | TYPED_TEST(HttpFetcherTest, ErrorTest) { | 
| Gilad Arnold | 9bedeb5 | 2011-11-17 16:19:57 -0800 | [diff] [blame] | 512 |   if (this->test_.IsMock() || this->test_.IsMulti()) | 
| Gilad Arnold | 48085ba | 2011-11-16 09:36:08 -0800 | [diff] [blame] | 513 |     return; | 
| Alex Deymo | 60ca1a7 | 2015-06-18 18:19:15 -0700 | [diff] [blame] | 514 |   HttpFetcherTestDelegate delegate; | 
| Gilad Arnold | 48085ba | 2011-11-16 09:36:08 -0800 | [diff] [blame] | 515 |  | 
| Alex Deymo | 60ca1a7 | 2015-06-18 18:19:15 -0700 | [diff] [blame] | 516 |   // Delegate should expect an error response. | 
 | 517 |   delegate.is_expect_error_ = true; | 
| Gilad Arnold | 48085ba | 2011-11-16 09:36:08 -0800 | [diff] [blame] | 518 |  | 
| Alex Deymo | 60ca1a7 | 2015-06-18 18:19:15 -0700 | [diff] [blame] | 519 |   unique_ptr<HttpFetcher> fetcher(this->test_.NewSmallFetcher()); | 
 | 520 |   fetcher->set_delegate(&delegate); | 
| Gilad Arnold | 48085ba | 2011-11-16 09:36:08 -0800 | [diff] [blame] | 521 |  | 
| Alex Deymo | 60ca1a7 | 2015-06-18 18:19:15 -0700 | [diff] [blame] | 522 |   unique_ptr<HttpServer> server(this->test_.CreateServer()); | 
 | 523 |   ASSERT_TRUE(server->started_); | 
| Gilad Arnold | 48085ba | 2011-11-16 09:36:08 -0800 | [diff] [blame] | 524 |  | 
| Amin Hassani | b268959 | 2019-01-13 17:04:28 -0800 | [diff] [blame] | 525 |   this->loop_.PostTask(FROM_HERE, | 
 | 526 |                        base::Bind(StartTransfer, | 
 | 527 |                                   fetcher.get(), | 
 | 528 |                                   this->test_.ErrorUrl(server->GetPort()))); | 
| Alex Deymo | 60ca1a7 | 2015-06-18 18:19:15 -0700 | [diff] [blame] | 529 |   this->loop_.Run(); | 
| Gilad Arnold | 48085ba | 2011-11-16 09:36:08 -0800 | [diff] [blame] | 530 |  | 
| Alex Deymo | 60ca1a7 | 2015-06-18 18:19:15 -0700 | [diff] [blame] | 531 |   // Make sure that no bytes were received. | 
| Alex Deymo | 71f6762 | 2017-02-03 21:30:24 -0800 | [diff] [blame] | 532 |   EXPECT_EQ(0, delegate.times_received_bytes_called_); | 
 | 533 |   EXPECT_EQ(0U, fetcher->GetBytesDownloaded()); | 
| Gilad Arnold | 48085ba | 2011-11-16 09:36:08 -0800 | [diff] [blame] | 534 |  | 
| Alex Deymo | 60ca1a7 | 2015-06-18 18:19:15 -0700 | [diff] [blame] | 535 |   // Make sure that transfer completion was signaled once, and no termination | 
 | 536 |   // was signaled. | 
| Alex Deymo | 71f6762 | 2017-02-03 21:30:24 -0800 | [diff] [blame] | 537 |   EXPECT_EQ(1, delegate.times_transfer_complete_called_); | 
 | 538 |   EXPECT_EQ(0, delegate.times_transfer_terminated_called_); | 
| Gilad Arnold | 48085ba | 2011-11-16 09:36:08 -0800 | [diff] [blame] | 539 | } | 
 | 540 |  | 
| Alex Deymo | fdd6dec | 2016-03-03 22:35:43 -0800 | [diff] [blame] | 541 | TYPED_TEST(HttpFetcherTest, ExtraHeadersInRequestTest) { | 
| Alex Deymo | 2c131bb | 2016-05-26 16:43:13 -0700 | [diff] [blame] | 542 |   if (this->test_.IsMock() || !this->test_.IsHttpSupported()) | 
| Alex Deymo | fdd6dec | 2016-03-03 22:35:43 -0800 | [diff] [blame] | 543 |     return; | 
 | 544 |  | 
 | 545 |   HttpFetcherTestDelegate delegate; | 
 | 546 |   unique_ptr<HttpFetcher> fetcher(this->test_.NewSmallFetcher()); | 
 | 547 |   fetcher->set_delegate(&delegate); | 
 | 548 |   fetcher->SetHeader("User-Agent", "MyTest"); | 
 | 549 |   fetcher->SetHeader("user-agent", "Override that header"); | 
 | 550 |   fetcher->SetHeader("Authorization", "Basic user:passwd"); | 
 | 551 |  | 
 | 552 |   // Invalid headers. | 
 | 553 |   fetcher->SetHeader("X-Foo", "Invalid\nHeader\nIgnored"); | 
 | 554 |   fetcher->SetHeader("X-Bar: ", "I do not know how to parse"); | 
 | 555 |  | 
 | 556 |   // Hide Accept header normally added by default. | 
 | 557 |   fetcher->SetHeader("Accept", ""); | 
 | 558 |  | 
 | 559 |   PythonHttpServer server; | 
 | 560 |   int port = server.GetPort(); | 
 | 561 |   ASSERT_TRUE(server.started_); | 
 | 562 |  | 
| Alex Deymo | 2c131bb | 2016-05-26 16:43:13 -0700 | [diff] [blame] | 563 |   this->loop_.PostTask( | 
 | 564 |       FROM_HERE, | 
 | 565 |       base::Bind(StartTransfer, | 
 | 566 |                  fetcher.get(), | 
 | 567 |                  LocalServerUrlForPath(port, "/echo-headers"))); | 
| Alex Deymo | fdd6dec | 2016-03-03 22:35:43 -0800 | [diff] [blame] | 568 |   this->loop_.Run(); | 
 | 569 |  | 
 | 570 |   EXPECT_NE(string::npos, | 
 | 571 |             delegate.data.find("user-agent: Override that header\r\n")); | 
 | 572 |   EXPECT_NE(string::npos, | 
 | 573 |             delegate.data.find("Authorization: Basic user:passwd\r\n")); | 
 | 574 |  | 
 | 575 |   EXPECT_EQ(string::npos, delegate.data.find("\nAccept:")); | 
 | 576 |   EXPECT_EQ(string::npos, delegate.data.find("X-Foo: Invalid")); | 
 | 577 |   EXPECT_EQ(string::npos, delegate.data.find("X-Bar: I do not")); | 
 | 578 | } | 
 | 579 |  | 
| rspangler@google.com | 49fdf18 | 2009-10-10 00:57:34 +0000 | [diff] [blame] | 580 | class PausingHttpFetcherTestDelegate : public HttpFetcherDelegate { | 
 | 581 |  public: | 
| Amin Hassani | 0cd9d77 | 2018-07-31 23:55:43 -0700 | [diff] [blame] | 582 |   bool ReceivedBytes(HttpFetcher* fetcher, | 
 | 583 |                      const void* /* bytes */, | 
 | 584 |                      size_t /* length */) override { | 
| rspangler@google.com | 49fdf18 | 2009-10-10 00:57:34 +0000 | [diff] [blame] | 585 |     CHECK(!paused_); | 
 | 586 |     paused_ = true; | 
 | 587 |     fetcher->Pause(); | 
| Amin Hassani | 0cd9d77 | 2018-07-31 23:55:43 -0700 | [diff] [blame] | 588 |     return true; | 
| rspangler@google.com | 49fdf18 | 2009-10-10 00:57:34 +0000 | [diff] [blame] | 589 |   } | 
| Alex Deymo | 610277e | 2014-11-11 21:18:11 -0800 | [diff] [blame] | 590 |   void TransferComplete(HttpFetcher* fetcher, bool successful) override { | 
| Alex Deymo | 60ca1a7 | 2015-06-18 18:19:15 -0700 | [diff] [blame] | 591 |     MessageLoop::current()->BreakLoop(); | 
| rspangler@google.com | 49fdf18 | 2009-10-10 00:57:34 +0000 | [diff] [blame] | 592 |   } | 
| Amin Hassani | b268959 | 2019-01-13 17:04:28 -0800 | [diff] [blame] | 593 |   void TransferTerminated(HttpFetcher* fetcher) override { ADD_FAILURE(); } | 
| rspangler@google.com | 49fdf18 | 2009-10-10 00:57:34 +0000 | [diff] [blame] | 594 |   void Unpause() { | 
 | 595 |     CHECK(paused_); | 
 | 596 |     paused_ = false; | 
 | 597 |     fetcher_->Unpause(); | 
| rspangler@google.com | 49fdf18 | 2009-10-10 00:57:34 +0000 | [diff] [blame] | 598 |   } | 
 | 599 |   bool paused_; | 
 | 600 |   HttpFetcher* fetcher_; | 
| rspangler@google.com | 49fdf18 | 2009-10-10 00:57:34 +0000 | [diff] [blame] | 601 | }; | 
 | 602 |  | 
| Alex Deymo | 60ca1a7 | 2015-06-18 18:19:15 -0700 | [diff] [blame] | 603 | void UnpausingTimeoutCallback(PausingHttpFetcherTestDelegate* delegate, | 
 | 604 |                               MessageLoop::TaskId* my_id) { | 
| rspangler@google.com | 49fdf18 | 2009-10-10 00:57:34 +0000 | [diff] [blame] | 605 |   if (delegate->paused_) | 
 | 606 |     delegate->Unpause(); | 
| Alex Deymo | 60ca1a7 | 2015-06-18 18:19:15 -0700 | [diff] [blame] | 607 |   // Update the task id with the new scheduled callback. | 
 | 608 |   *my_id = MessageLoop::current()->PostDelayedTask( | 
 | 609 |       FROM_HERE, | 
 | 610 |       base::Bind(&UnpausingTimeoutCallback, delegate, my_id), | 
 | 611 |       base::TimeDelta::FromMilliseconds(200)); | 
| rspangler@google.com | 49fdf18 | 2009-10-10 00:57:34 +0000 | [diff] [blame] | 612 | } | 
| rspangler@google.com | 49fdf18 | 2009-10-10 00:57:34 +0000 | [diff] [blame] | 613 |  | 
 | 614 | TYPED_TEST(HttpFetcherTest, PauseTest) { | 
| Alex Deymo | f285857 | 2016-02-25 11:20:13 -0800 | [diff] [blame] | 615 |   PausingHttpFetcherTestDelegate delegate; | 
 | 616 |   unique_ptr<HttpFetcher> fetcher(this->test_.NewLargeFetcher()); | 
 | 617 |   delegate.paused_ = false; | 
 | 618 |   delegate.fetcher_ = fetcher.get(); | 
 | 619 |   fetcher->set_delegate(&delegate); | 
| rspangler@google.com | 49fdf18 | 2009-10-10 00:57:34 +0000 | [diff] [blame] | 620 |  | 
| Alex Deymo | f285857 | 2016-02-25 11:20:13 -0800 | [diff] [blame] | 621 |   unique_ptr<HttpServer> server(this->test_.CreateServer()); | 
 | 622 |   ASSERT_TRUE(server->started_); | 
| Andrew de los Reyes | f3ed8e7 | 2011-02-16 10:35:46 -0800 | [diff] [blame] | 623 |  | 
| Daniel Zheng | 3e881aa | 2022-09-07 22:10:29 +0000 | [diff] [blame] | 624 |   MessageLoop::TaskId callback_id{}; | 
| Alex Deymo | f285857 | 2016-02-25 11:20:13 -0800 | [diff] [blame] | 625 |   callback_id = this->loop_.PostDelayedTask( | 
 | 626 |       FROM_HERE, | 
 | 627 |       base::Bind(&UnpausingTimeoutCallback, &delegate, &callback_id), | 
 | 628 |       base::TimeDelta::FromMilliseconds(200)); | 
 | 629 |   fetcher->BeginTransfer(this->test_.BigUrl(server->GetPort())); | 
| rspangler@google.com | 49fdf18 | 2009-10-10 00:57:34 +0000 | [diff] [blame] | 630 |  | 
| Alex Deymo | f285857 | 2016-02-25 11:20:13 -0800 | [diff] [blame] | 631 |   this->loop_.Run(); | 
 | 632 |   EXPECT_TRUE(this->loop_.CancelTask(callback_id)); | 
 | 633 | } | 
 | 634 |  | 
 | 635 | // This test will pause the fetcher while the download is not yet started | 
 | 636 | // because it is waiting for the proxy to be resolved. | 
 | 637 | TYPED_TEST(HttpFetcherTest, PauseWhileResolvingProxyTest) { | 
| Alex Deymo | 2c131bb | 2016-05-26 16:43:13 -0700 | [diff] [blame] | 638 |   if (this->test_.IsMock() || !this->test_.IsHttpSupported()) | 
| Alex Deymo | f285857 | 2016-02-25 11:20:13 -0800 | [diff] [blame] | 639 |     return; | 
| Kelvin Zhang | c7a1d1f | 2022-07-29 13:36:29 -0700 | [diff] [blame] | 640 |   unique_ptr<HttpFetcher> fetcher(this->test_.NewLargeFetcher()); | 
| Alex Deymo | f285857 | 2016-02-25 11:20:13 -0800 | [diff] [blame] | 641 |  | 
 | 642 |   // Saved arguments from the proxy call. | 
| Alex Deymo | f285857 | 2016-02-25 11:20:13 -0800 | [diff] [blame] | 643 |   fetcher->BeginTransfer("http://fake_url"); | 
| Alex Deymo | f285857 | 2016-02-25 11:20:13 -0800 | [diff] [blame] | 644 |  | 
 | 645 |   // Pausing and unpausing while resolving the proxy should not affect anything. | 
 | 646 |   fetcher->Pause(); | 
 | 647 |   fetcher->Unpause(); | 
 | 648 |   fetcher->Pause(); | 
 | 649 |   // Proxy resolver comes back after we paused the fetcher. | 
| rspangler@google.com | 49fdf18 | 2009-10-10 00:57:34 +0000 | [diff] [blame] | 650 | } | 
 | 651 |  | 
| rspangler@google.com | 49fdf18 | 2009-10-10 00:57:34 +0000 | [diff] [blame] | 652 | class AbortingHttpFetcherTestDelegate : public HttpFetcherDelegate { | 
 | 653 |  public: | 
| Amin Hassani | 0cd9d77 | 2018-07-31 23:55:43 -0700 | [diff] [blame] | 654 |   bool ReceivedBytes(HttpFetcher* fetcher, | 
 | 655 |                      const void* bytes, | 
 | 656 |                      size_t length) override { | 
 | 657 |     return true; | 
 | 658 |   } | 
| Alex Deymo | 610277e | 2014-11-11 21:18:11 -0800 | [diff] [blame] | 659 |   void TransferComplete(HttpFetcher* fetcher, bool successful) override { | 
| Darin Petkov | 9ce452b | 2010-11-17 14:33:28 -0800 | [diff] [blame] | 660 |     ADD_FAILURE();  // We should never get here | 
| Alex Deymo | 60ca1a7 | 2015-06-18 18:19:15 -0700 | [diff] [blame] | 661 |     MessageLoop::current()->BreakLoop(); | 
| rspangler@google.com | 49fdf18 | 2009-10-10 00:57:34 +0000 | [diff] [blame] | 662 |   } | 
| Alex Deymo | 610277e | 2014-11-11 21:18:11 -0800 | [diff] [blame] | 663 |   void TransferTerminated(HttpFetcher* fetcher) override { | 
| Darin Petkov | 9ce452b | 2010-11-17 14:33:28 -0800 | [diff] [blame] | 664 |     EXPECT_EQ(fetcher, fetcher_.get()); | 
 | 665 |     EXPECT_FALSE(once_); | 
 | 666 |     EXPECT_TRUE(callback_once_); | 
 | 667 |     callback_once_ = false; | 
| Alex Deymo | c4acdf4 | 2014-05-28 21:07:10 -0700 | [diff] [blame] | 668 |     // The fetcher could have a callback scheduled on the ProxyResolver that | 
 | 669 |     // can fire after this callback. We wait until the end of the test to | 
 | 670 |     // delete the fetcher. | 
| Andrew de los Reyes | 819fef2 | 2010-12-17 11:33:58 -0800 | [diff] [blame] | 671 |   } | 
| rspangler@google.com | 49fdf18 | 2009-10-10 00:57:34 +0000 | [diff] [blame] | 672 |   void TerminateTransfer() { | 
 | 673 |     CHECK(once_); | 
 | 674 |     once_ = false; | 
 | 675 |     fetcher_->TerminateTransfer(); | 
 | 676 |   } | 
| Amin Hassani | b268959 | 2019-01-13 17:04:28 -0800 | [diff] [blame] | 677 |   void EndLoop() { MessageLoop::current()->BreakLoop(); } | 
| rspangler@google.com | 49fdf18 | 2009-10-10 00:57:34 +0000 | [diff] [blame] | 678 |   bool once_; | 
| Darin Petkov | 9ce452b | 2010-11-17 14:33:28 -0800 | [diff] [blame] | 679 |   bool callback_once_; | 
| Ben Chan | 02f7c1d | 2014-10-18 15:18:02 -0700 | [diff] [blame] | 680 |   unique_ptr<HttpFetcher> fetcher_; | 
| rspangler@google.com | 49fdf18 | 2009-10-10 00:57:34 +0000 | [diff] [blame] | 681 | }; | 
 | 682 |  | 
| Alex Deymo | 60ca1a7 | 2015-06-18 18:19:15 -0700 | [diff] [blame] | 683 | void AbortingTimeoutCallback(AbortingHttpFetcherTestDelegate* delegate, | 
 | 684 |                              MessageLoop::TaskId* my_id) { | 
| rspangler@google.com | 49fdf18 | 2009-10-10 00:57:34 +0000 | [diff] [blame] | 685 |   if (delegate->once_) { | 
 | 686 |     delegate->TerminateTransfer(); | 
| Alex Deymo | 60ca1a7 | 2015-06-18 18:19:15 -0700 | [diff] [blame] | 687 |     *my_id = MessageLoop::current()->PostTask( | 
| Amin Hassani | b268959 | 2019-01-13 17:04:28 -0800 | [diff] [blame] | 688 |         FROM_HERE, base::Bind(AbortingTimeoutCallback, delegate, my_id)); | 
| rspangler@google.com | 49fdf18 | 2009-10-10 00:57:34 +0000 | [diff] [blame] | 689 |   } else { | 
 | 690 |     delegate->EndLoop(); | 
| Alex Deymo | 60ca1a7 | 2015-06-18 18:19:15 -0700 | [diff] [blame] | 691 |     *my_id = MessageLoop::kTaskIdNull; | 
| rspangler@google.com | 49fdf18 | 2009-10-10 00:57:34 +0000 | [diff] [blame] | 692 |   } | 
 | 693 | } | 
| rspangler@google.com | 49fdf18 | 2009-10-10 00:57:34 +0000 | [diff] [blame] | 694 |  | 
 | 695 | TYPED_TEST(HttpFetcherTest, AbortTest) { | 
| Alex Deymo | 60ca1a7 | 2015-06-18 18:19:15 -0700 | [diff] [blame] | 696 |   AbortingHttpFetcherTestDelegate delegate; | 
 | 697 |   delegate.fetcher_.reset(this->test_.NewLargeFetcher()); | 
 | 698 |   delegate.once_ = true; | 
 | 699 |   delegate.callback_once_ = true; | 
 | 700 |   delegate.fetcher_->set_delegate(&delegate); | 
| rspangler@google.com | 49fdf18 | 2009-10-10 00:57:34 +0000 | [diff] [blame] | 701 |  | 
| Alex Deymo | 60ca1a7 | 2015-06-18 18:19:15 -0700 | [diff] [blame] | 702 |   unique_ptr<HttpServer> server(this->test_.CreateServer()); | 
 | 703 |   this->test_.IgnoreServerAborting(server.get()); | 
 | 704 |   ASSERT_TRUE(server->started_); | 
| Gilad Arnold | 9bedeb5 | 2011-11-17 16:19:57 -0800 | [diff] [blame] | 705 |  | 
| Alex Deymo | 60ca1a7 | 2015-06-18 18:19:15 -0700 | [diff] [blame] | 706 |   MessageLoop::TaskId task_id = MessageLoop::kTaskIdNull; | 
| rspangler@google.com | 49fdf18 | 2009-10-10 00:57:34 +0000 | [diff] [blame] | 707 |  | 
| Alex Deymo | 60ca1a7 | 2015-06-18 18:19:15 -0700 | [diff] [blame] | 708 |   task_id = this->loop_.PostTask( | 
| Amin Hassani | b268959 | 2019-01-13 17:04:28 -0800 | [diff] [blame] | 709 |       FROM_HERE, base::Bind(AbortingTimeoutCallback, &delegate, &task_id)); | 
| Alex Deymo | 60ca1a7 | 2015-06-18 18:19:15 -0700 | [diff] [blame] | 710 |   delegate.fetcher_->BeginTransfer(this->test_.BigUrl(server->GetPort())); | 
 | 711 |  | 
 | 712 |   this->loop_.Run(); | 
 | 713 |   CHECK(!delegate.once_); | 
 | 714 |   CHECK(!delegate.callback_once_); | 
 | 715 |   this->loop_.CancelTask(task_id); | 
| rspangler@google.com | 49fdf18 | 2009-10-10 00:57:34 +0000 | [diff] [blame] | 716 | } | 
 | 717 |  | 
| Alex Deymo | 71f6762 | 2017-02-03 21:30:24 -0800 | [diff] [blame] | 718 | TYPED_TEST(HttpFetcherTest, TerminateTransferWhileResolvingProxyTest) { | 
 | 719 |   if (this->test_.IsMock() || !this->test_.IsHttpSupported()) | 
 | 720 |     return; | 
| Kelvin Zhang | c7a1d1f | 2022-07-29 13:36:29 -0700 | [diff] [blame] | 721 |   unique_ptr<HttpFetcher> fetcher(this->test_.NewLargeFetcher()); | 
| Alex Deymo | 71f6762 | 2017-02-03 21:30:24 -0800 | [diff] [blame] | 722 |  | 
 | 723 |   HttpFetcherTestDelegate delegate; | 
 | 724 |   fetcher->set_delegate(&delegate); | 
 | 725 |  | 
| Alex Deymo | 71f6762 | 2017-02-03 21:30:24 -0800 | [diff] [blame] | 726 |   fetcher->BeginTransfer("http://fake_url"); | 
 | 727 |   // Run the message loop until idle. This must call the MockProxyResolver with | 
 | 728 |   // the request. | 
 | 729 |   while (this->loop_.RunOnce(false)) { | 
 | 730 |   } | 
| Alex Deymo | 71f6762 | 2017-02-03 21:30:24 -0800 | [diff] [blame] | 731 |  | 
 | 732 |   // Terminate the transfer right before the proxy resolution response. | 
 | 733 |   fetcher->TerminateTransfer(); | 
 | 734 |   EXPECT_EQ(0, delegate.times_received_bytes_called_); | 
 | 735 |   EXPECT_EQ(0, delegate.times_transfer_complete_called_); | 
 | 736 |   EXPECT_EQ(1, delegate.times_transfer_terminated_called_); | 
 | 737 | } | 
 | 738 |  | 
| adlr@google.com | c98a7ed | 2009-12-04 18:54:03 +0000 | [diff] [blame] | 739 | class FlakyHttpFetcherTestDelegate : public HttpFetcherDelegate { | 
 | 740 |  public: | 
| Amin Hassani | 0cd9d77 | 2018-07-31 23:55:43 -0700 | [diff] [blame] | 741 |   bool ReceivedBytes(HttpFetcher* fetcher, | 
 | 742 |                      const void* bytes, | 
 | 743 |                      size_t length) override { | 
| Alex Vakulenko | f68bbbc | 2015-02-09 12:53:18 -0800 | [diff] [blame] | 744 |     data.append(reinterpret_cast<const char*>(bytes), length); | 
| Amin Hassani | 0cd9d77 | 2018-07-31 23:55:43 -0700 | [diff] [blame] | 745 |     return true; | 
| adlr@google.com | c98a7ed | 2009-12-04 18:54:03 +0000 | [diff] [blame] | 746 |   } | 
| Alex Deymo | 610277e | 2014-11-11 21:18:11 -0800 | [diff] [blame] | 747 |   void TransferComplete(HttpFetcher* fetcher, bool successful) override { | 
| Andrew de los Reyes | fb4ad7d | 2010-07-19 10:43:46 -0700 | [diff] [blame] | 748 |     EXPECT_TRUE(successful); | 
| Gilad Arnold | 9bedeb5 | 2011-11-17 16:19:57 -0800 | [diff] [blame] | 749 |     EXPECT_EQ(kHttpResponsePartialContent, fetcher->http_response_code()); | 
| Alex Deymo | 60ca1a7 | 2015-06-18 18:19:15 -0700 | [diff] [blame] | 750 |     MessageLoop::current()->BreakLoop(); | 
| adlr@google.com | c98a7ed | 2009-12-04 18:54:03 +0000 | [diff] [blame] | 751 |   } | 
| Amin Hassani | b268959 | 2019-01-13 17:04:28 -0800 | [diff] [blame] | 752 |   void TransferTerminated(HttpFetcher* fetcher) override { ADD_FAILURE(); } | 
| adlr@google.com | c98a7ed | 2009-12-04 18:54:03 +0000 | [diff] [blame] | 753 |   string data; | 
| adlr@google.com | c98a7ed | 2009-12-04 18:54:03 +0000 | [diff] [blame] | 754 | }; | 
| adlr@google.com | c98a7ed | 2009-12-04 18:54:03 +0000 | [diff] [blame] | 755 |  | 
 | 756 | TYPED_TEST(HttpFetcherTest, FlakyTest) { | 
| Alex Deymo | 2c131bb | 2016-05-26 16:43:13 -0700 | [diff] [blame] | 757 |   if (this->test_.IsMock() || !this->test_.IsHttpSupported()) | 
| adlr@google.com | c98a7ed | 2009-12-04 18:54:03 +0000 | [diff] [blame] | 758 |     return; | 
| adlr@google.com | c98a7ed | 2009-12-04 18:54:03 +0000 | [diff] [blame] | 759 |   { | 
 | 760 |     FlakyHttpFetcherTestDelegate delegate; | 
| Ben Chan | 02f7c1d | 2014-10-18 15:18:02 -0700 | [diff] [blame] | 761 |     unique_ptr<HttpFetcher> fetcher(this->test_.NewSmallFetcher()); | 
| adlr@google.com | c98a7ed | 2009-12-04 18:54:03 +0000 | [diff] [blame] | 762 |     fetcher->set_delegate(&delegate); | 
 | 763 |  | 
| Ben Chan | 02f7c1d | 2014-10-18 15:18:02 -0700 | [diff] [blame] | 764 |     unique_ptr<HttpServer> server(this->test_.CreateServer()); | 
| Gilad Arnold | 9bedeb5 | 2011-11-17 16:19:57 -0800 | [diff] [blame] | 765 |     ASSERT_TRUE(server->started_); | 
| adlr@google.com | c98a7ed | 2009-12-04 18:54:03 +0000 | [diff] [blame] | 766 |  | 
| Amin Hassani | b268959 | 2019-01-13 17:04:28 -0800 | [diff] [blame] | 767 |     this->loop_.PostTask(FROM_HERE, | 
 | 768 |                          base::Bind(&StartTransfer, | 
 | 769 |                                     fetcher.get(), | 
 | 770 |                                     LocalServerUrlForPath( | 
 | 771 |                                         server->GetPort(), | 
 | 772 |                                         base::StringPrintf("/flaky/%d/%d/%d/%d", | 
 | 773 |                                                            kBigLength, | 
 | 774 |                                                            kFlakyTruncateLength, | 
 | 775 |                                                            kFlakySleepEvery, | 
 | 776 |                                                            kFlakySleepSecs)))); | 
| Alex Deymo | 60ca1a7 | 2015-06-18 18:19:15 -0700 | [diff] [blame] | 777 |     this->loop_.Run(); | 
| adlr@google.com | c98a7ed | 2009-12-04 18:54:03 +0000 | [diff] [blame] | 778 |  | 
 | 779 |     // verify the data we get back | 
| Alex Deymo | 80f70ff | 2016-02-10 16:08:11 -0800 | [diff] [blame] | 780 |     ASSERT_EQ(kBigLength, static_cast<int>(delegate.data.size())); | 
| Gilad Arnold | 9bedeb5 | 2011-11-17 16:19:57 -0800 | [diff] [blame] | 781 |     for (int i = 0; i < kBigLength; i += 10) { | 
| adlr@google.com | c98a7ed | 2009-12-04 18:54:03 +0000 | [diff] [blame] | 782 |       // Assert so that we don't flood the screen w/ EXPECT errors on failure. | 
 | 783 |       ASSERT_EQ(delegate.data.substr(i, 10), "abcdefghij"); | 
 | 784 |     } | 
 | 785 |   } | 
| adlr@google.com | c98a7ed | 2009-12-04 18:54:03 +0000 | [diff] [blame] | 786 | } | 
 | 787 |  | 
| Chris Sosa | 0a364bb | 2014-06-10 18:18:24 -0700 | [diff] [blame] | 788 | // This delegate kills the server attached to it after receiving any bytes. | 
 | 789 | // This can be used for testing what happens when you try to fetch data and | 
 | 790 | // the server dies. | 
| Andrew de los Reyes | 9bbd187 | 2010-07-16 14:52:29 -0700 | [diff] [blame] | 791 | class FailureHttpFetcherTestDelegate : public HttpFetcherDelegate { | 
 | 792 |  public: | 
| Alex Vakulenko | d2779df | 2014-06-16 13:19:00 -0700 | [diff] [blame] | 793 |   explicit FailureHttpFetcherTestDelegate(PythonHttpServer* server) | 
| Alex Deymo | 60ca1a7 | 2015-06-18 18:19:15 -0700 | [diff] [blame] | 794 |       : server_(server) {} | 
| Jay Srinivasan | 135a58b | 2012-07-13 12:46:49 -0700 | [diff] [blame] | 795 |  | 
| Alex Deymo | 610277e | 2014-11-11 21:18:11 -0800 | [diff] [blame] | 796 |   ~FailureHttpFetcherTestDelegate() override { | 
| Jay Srinivasan | 135a58b | 2012-07-13 12:46:49 -0700 | [diff] [blame] | 797 |     if (server_) { | 
 | 798 |       LOG(INFO) << "Stopping server in destructor"; | 
| Alex Deymo | b20de69 | 2017-02-05 07:47:37 +0000 | [diff] [blame] | 799 |       server_.reset(); | 
| Jay Srinivasan | 135a58b | 2012-07-13 12:46:49 -0700 | [diff] [blame] | 800 |       LOG(INFO) << "server stopped"; | 
 | 801 |     } | 
 | 802 |   } | 
 | 803 |  | 
| Amin Hassani | 0cd9d77 | 2018-07-31 23:55:43 -0700 | [diff] [blame] | 804 |   bool ReceivedBytes(HttpFetcher* fetcher, | 
 | 805 |                      const void* bytes, | 
 | 806 |                      size_t length) override { | 
| Andrew de los Reyes | 9bbd187 | 2010-07-16 14:52:29 -0700 | [diff] [blame] | 807 |     if (server_) { | 
| Jay Srinivasan | 135a58b | 2012-07-13 12:46:49 -0700 | [diff] [blame] | 808 |       LOG(INFO) << "Stopping server in ReceivedBytes"; | 
| Alex Deymo | b20de69 | 2017-02-05 07:47:37 +0000 | [diff] [blame] | 809 |       server_.reset(); | 
| Andrew de los Reyes | 9bbd187 | 2010-07-16 14:52:29 -0700 | [diff] [blame] | 810 |       LOG(INFO) << "server stopped"; | 
| Andrew de los Reyes | 9bbd187 | 2010-07-16 14:52:29 -0700 | [diff] [blame] | 811 |     } | 
| Amin Hassani | 0cd9d77 | 2018-07-31 23:55:43 -0700 | [diff] [blame] | 812 |     return true; | 
| Andrew de los Reyes | 9bbd187 | 2010-07-16 14:52:29 -0700 | [diff] [blame] | 813 |   } | 
| Alex Deymo | 610277e | 2014-11-11 21:18:11 -0800 | [diff] [blame] | 814 |   void TransferComplete(HttpFetcher* fetcher, bool successful) override { | 
| Andrew de los Reyes | 9bbd187 | 2010-07-16 14:52:29 -0700 | [diff] [blame] | 815 |     EXPECT_FALSE(successful); | 
| Chris Sosa | 0a364bb | 2014-06-10 18:18:24 -0700 | [diff] [blame] | 816 |     EXPECT_EQ(0, fetcher->http_response_code()); | 
| Alex Deymo | b20de69 | 2017-02-05 07:47:37 +0000 | [diff] [blame] | 817 |     times_transfer_complete_called_++; | 
| Alex Deymo | 60ca1a7 | 2015-06-18 18:19:15 -0700 | [diff] [blame] | 818 |     MessageLoop::current()->BreakLoop(); | 
| Andrew de los Reyes | 9bbd187 | 2010-07-16 14:52:29 -0700 | [diff] [blame] | 819 |   } | 
| Alex Deymo | 610277e | 2014-11-11 21:18:11 -0800 | [diff] [blame] | 820 |   void TransferTerminated(HttpFetcher* fetcher) override { | 
| Alex Deymo | b20de69 | 2017-02-05 07:47:37 +0000 | [diff] [blame] | 821 |     times_transfer_terminated_called_++; | 
 | 822 |     MessageLoop::current()->BreakLoop(); | 
| Darin Petkov | 9ce452b | 2010-11-17 14:33:28 -0800 | [diff] [blame] | 823 |   } | 
| Alex Deymo | b20de69 | 2017-02-05 07:47:37 +0000 | [diff] [blame] | 824 |   unique_ptr<PythonHttpServer> server_; | 
 | 825 |   int times_transfer_terminated_called_{0}; | 
 | 826 |   int times_transfer_complete_called_{0}; | 
| Andrew de los Reyes | 9bbd187 | 2010-07-16 14:52:29 -0700 | [diff] [blame] | 827 | }; | 
| Andrew de los Reyes | 9bbd187 | 2010-07-16 14:52:29 -0700 | [diff] [blame] | 828 |  | 
| Andrew de los Reyes | 9bbd187 | 2010-07-16 14:52:29 -0700 | [diff] [blame] | 829 | TYPED_TEST(HttpFetcherTest, FailureTest) { | 
| Chris Sosa | 0a364bb | 2014-06-10 18:18:24 -0700 | [diff] [blame] | 830 |   // This test ensures that a fetcher responds correctly when a server isn't | 
 | 831 |   // available at all. | 
| Gilad Arnold | 9bedeb5 | 2011-11-17 16:19:57 -0800 | [diff] [blame] | 832 |   if (this->test_.IsMock()) | 
| Andrew de los Reyes | 9bbd187 | 2010-07-16 14:52:29 -0700 | [diff] [blame] | 833 |     return; | 
| Alex Deymo | b20de69 | 2017-02-05 07:47:37 +0000 | [diff] [blame] | 834 |   FailureHttpFetcherTestDelegate delegate(nullptr); | 
 | 835 |   unique_ptr<HttpFetcher> fetcher(this->test_.NewSmallFetcher()); | 
 | 836 |   fetcher->set_delegate(&delegate); | 
| Andrew de los Reyes | 9bbd187 | 2010-07-16 14:52:29 -0700 | [diff] [blame] | 837 |  | 
| Alex Deymo | b20de69 | 2017-02-05 07:47:37 +0000 | [diff] [blame] | 838 |   this->loop_.PostTask( | 
 | 839 |       FROM_HERE, | 
 | 840 |       base::Bind( | 
 | 841 |           StartTransfer, fetcher.get(), "http://host_doesnt_exist99999999")); | 
 | 842 |   this->loop_.Run(); | 
 | 843 |   EXPECT_EQ(1, delegate.times_transfer_complete_called_); | 
 | 844 |   EXPECT_EQ(0, delegate.times_transfer_terminated_called_); | 
| Andrew de los Reyes | 9bbd187 | 2010-07-16 14:52:29 -0700 | [diff] [blame] | 845 |  | 
| Alex Deymo | b20de69 | 2017-02-05 07:47:37 +0000 | [diff] [blame] | 846 |   // Exiting and testing happens in the delegate | 
| Andrew de los Reyes | 9bbd187 | 2010-07-16 14:52:29 -0700 | [diff] [blame] | 847 | } | 
 | 848 |  | 
| Alex Deymo | f123ae2 | 2015-09-24 14:59:43 -0700 | [diff] [blame] | 849 | TYPED_TEST(HttpFetcherTest, NoResponseTest) { | 
 | 850 |   // This test starts a new http server but the server doesn't respond and just | 
 | 851 |   // closes the connection. | 
 | 852 |   if (this->test_.IsMock()) | 
 | 853 |     return; | 
 | 854 |  | 
 | 855 |   PythonHttpServer* server = new PythonHttpServer(); | 
 | 856 |   int port = server->GetPort(); | 
 | 857 |   ASSERT_TRUE(server->started_); | 
 | 858 |  | 
 | 859 |   // Handles destruction and claims ownership. | 
 | 860 |   FailureHttpFetcherTestDelegate delegate(server); | 
 | 861 |   unique_ptr<HttpFetcher> fetcher(this->test_.NewSmallFetcher()); | 
 | 862 |   fetcher->set_delegate(&delegate); | 
 | 863 |   // The server will not reply at all, so we can limit the execution time of the | 
 | 864 |   // test by reducing the low-speed timeout to something small. The test will | 
 | 865 |   // finish once the TimeoutCallback() triggers (every second) and the timeout | 
 | 866 |   // expired. | 
 | 867 |   fetcher->set_low_speed_limit(kDownloadLowSpeedLimitBps, 1); | 
 | 868 |  | 
| Amin Hassani | b268959 | 2019-01-13 17:04:28 -0800 | [diff] [blame] | 869 |   this->loop_.PostTask( | 
 | 870 |       FROM_HERE, | 
 | 871 |       base::Bind( | 
 | 872 |           StartTransfer, fetcher.get(), LocalServerUrlForPath(port, "/hang"))); | 
| Alex Deymo | f123ae2 | 2015-09-24 14:59:43 -0700 | [diff] [blame] | 873 |   this->loop_.Run(); | 
| Alex Deymo | b20de69 | 2017-02-05 07:47:37 +0000 | [diff] [blame] | 874 |   EXPECT_EQ(1, delegate.times_transfer_complete_called_); | 
 | 875 |   EXPECT_EQ(0, delegate.times_transfer_terminated_called_); | 
| Alex Deymo | f123ae2 | 2015-09-24 14:59:43 -0700 | [diff] [blame] | 876 |  | 
 | 877 |   // Check that no other callback runs in the next two seconds. That would | 
 | 878 |   // indicate a leaked callback. | 
 | 879 |   bool timeout = false; | 
| Luis Hector Chavez | f1cf348 | 2016-07-19 14:29:19 -0700 | [diff] [blame] | 880 |   auto callback = base::Bind([](bool* timeout) { *timeout = true; }, | 
 | 881 |                              base::Unretained(&timeout)); | 
| Amin Hassani | b268959 | 2019-01-13 17:04:28 -0800 | [diff] [blame] | 882 |   this->loop_.PostDelayedTask( | 
 | 883 |       FROM_HERE, callback, base::TimeDelta::FromSeconds(2)); | 
| Alex Deymo | f123ae2 | 2015-09-24 14:59:43 -0700 | [diff] [blame] | 884 |   EXPECT_TRUE(this->loop_.RunOnce(true)); | 
 | 885 |   EXPECT_TRUE(timeout); | 
 | 886 | } | 
 | 887 |  | 
| Andrew de los Reyes | 9bbd187 | 2010-07-16 14:52:29 -0700 | [diff] [blame] | 888 | TYPED_TEST(HttpFetcherTest, ServerDiesTest) { | 
| Chris Sosa | 0a364bb | 2014-06-10 18:18:24 -0700 | [diff] [blame] | 889 |   // This test starts a new http server and kills it after receiving its first | 
 | 890 |   // set of bytes. It test whether or not our fetcher eventually gives up on | 
 | 891 |   // retries and aborts correctly. | 
| Gilad Arnold | 9bedeb5 | 2011-11-17 16:19:57 -0800 | [diff] [blame] | 892 |   if (this->test_.IsMock()) | 
| Andrew de los Reyes | 9bbd187 | 2010-07-16 14:52:29 -0700 | [diff] [blame] | 893 |     return; | 
| Alex Deymo | b20de69 | 2017-02-05 07:47:37 +0000 | [diff] [blame] | 894 |   PythonHttpServer* server = new PythonHttpServer(); | 
 | 895 |   int port = server->GetPort(); | 
 | 896 |   ASSERT_TRUE(server->started_); | 
| Chris Sosa | 0a364bb | 2014-06-10 18:18:24 -0700 | [diff] [blame] | 897 |  | 
| Alex Deymo | b20de69 | 2017-02-05 07:47:37 +0000 | [diff] [blame] | 898 |   // Handles destruction and claims ownership. | 
 | 899 |   FailureHttpFetcherTestDelegate delegate(server); | 
 | 900 |   unique_ptr<HttpFetcher> fetcher(this->test_.NewSmallFetcher()); | 
 | 901 |   fetcher->set_delegate(&delegate); | 
| Andrew de los Reyes | 9bbd187 | 2010-07-16 14:52:29 -0700 | [diff] [blame] | 902 |  | 
| Alex Deymo | b20de69 | 2017-02-05 07:47:37 +0000 | [diff] [blame] | 903 |   this->loop_.PostTask( | 
 | 904 |       FROM_HERE, | 
 | 905 |       base::Bind(StartTransfer, | 
 | 906 |                  fetcher.get(), | 
 | 907 |                  LocalServerUrlForPath(port, | 
 | 908 |                                        base::StringPrintf("/flaky/%d/%d/%d/%d", | 
 | 909 |                                                           kBigLength, | 
 | 910 |                                                           kFlakyTruncateLength, | 
 | 911 |                                                           kFlakySleepEvery, | 
 | 912 |                                                           kFlakySleepSecs)))); | 
 | 913 |   this->loop_.Run(); | 
 | 914 |   EXPECT_EQ(1, delegate.times_transfer_complete_called_); | 
 | 915 |   EXPECT_EQ(0, delegate.times_transfer_terminated_called_); | 
| Andrew de los Reyes | 9bbd187 | 2010-07-16 14:52:29 -0700 | [diff] [blame] | 916 |  | 
| Alex Deymo | b20de69 | 2017-02-05 07:47:37 +0000 | [diff] [blame] | 917 |   // Exiting and testing happens in the delegate | 
 | 918 | } | 
 | 919 |  | 
 | 920 | // Test that we can cancel a transfer while it is still trying to connect to the | 
 | 921 | // server. This test kills the server after a few bytes are received. | 
 | 922 | TYPED_TEST(HttpFetcherTest, TerminateTransferWhenServerDiedTest) { | 
 | 923 |   if (this->test_.IsMock() || !this->test_.IsHttpSupported()) | 
 | 924 |     return; | 
 | 925 |  | 
 | 926 |   PythonHttpServer* server = new PythonHttpServer(); | 
 | 927 |   int port = server->GetPort(); | 
 | 928 |   ASSERT_TRUE(server->started_); | 
 | 929 |  | 
 | 930 |   // Handles destruction and claims ownership. | 
 | 931 |   FailureHttpFetcherTestDelegate delegate(server); | 
 | 932 |   unique_ptr<HttpFetcher> fetcher(this->test_.NewSmallFetcher()); | 
 | 933 |   fetcher->set_delegate(&delegate); | 
 | 934 |  | 
 | 935 |   this->loop_.PostTask( | 
 | 936 |       FROM_HERE, | 
 | 937 |       base::Bind(StartTransfer, | 
 | 938 |                  fetcher.get(), | 
 | 939 |                  LocalServerUrlForPath(port, | 
 | 940 |                                        base::StringPrintf("/flaky/%d/%d/%d/%d", | 
 | 941 |                                                           kBigLength, | 
 | 942 |                                                           kFlakyTruncateLength, | 
 | 943 |                                                           kFlakySleepEvery, | 
 | 944 |                                                           kFlakySleepSecs)))); | 
 | 945 |   // Terminating the transfer after 3 seconds gives it a chance to contact the | 
 | 946 |   // server and enter the retry loop. | 
 | 947 |   this->loop_.PostDelayedTask(FROM_HERE, | 
 | 948 |                               base::Bind(&HttpFetcher::TerminateTransfer, | 
 | 949 |                                          base::Unretained(fetcher.get())), | 
 | 950 |                               base::TimeDelta::FromSeconds(3)); | 
 | 951 |  | 
 | 952 |   // Exiting and testing happens in the delegate. | 
 | 953 |   this->loop_.Run(); | 
 | 954 |   EXPECT_EQ(0, delegate.times_transfer_complete_called_); | 
 | 955 |   EXPECT_EQ(1, delegate.times_transfer_terminated_called_); | 
 | 956 |  | 
 | 957 |   // Check that no other callback runs in the next two seconds. That would | 
 | 958 |   // indicate a leaked callback. | 
 | 959 |   bool timeout = false; | 
 | 960 |   auto callback = base::Bind([](bool* timeout) { *timeout = true; }, | 
 | 961 |                              base::Unretained(&timeout)); | 
 | 962 |   this->loop_.PostDelayedTask( | 
 | 963 |       FROM_HERE, callback, base::TimeDelta::FromSeconds(2)); | 
 | 964 |   EXPECT_TRUE(this->loop_.RunOnce(true)); | 
 | 965 |   EXPECT_TRUE(timeout); | 
| Andrew de los Reyes | 9bbd187 | 2010-07-16 14:52:29 -0700 | [diff] [blame] | 966 | } | 
 | 967 |  | 
| Amin Hassani | b268959 | 2019-01-13 17:04:28 -0800 | [diff] [blame] | 968 | const HttpResponseCode kRedirectCodes[] = {kHttpResponseMovedPermanently, | 
 | 969 |                                            kHttpResponseFound, | 
 | 970 |                                            kHttpResponseSeeOther, | 
 | 971 |                                            kHttpResponseTempRedirect}; | 
| Darin Petkov | 41c2fcf | 2010-08-25 13:14:48 -0700 | [diff] [blame] | 972 |  | 
 | 973 | class RedirectHttpFetcherTestDelegate : public HttpFetcherDelegate { | 
 | 974 |  public: | 
| Alex Vakulenko | d2779df | 2014-06-16 13:19:00 -0700 | [diff] [blame] | 975 |   explicit RedirectHttpFetcherTestDelegate(bool expected_successful) | 
| Darin Petkov | 41c2fcf | 2010-08-25 13:14:48 -0700 | [diff] [blame] | 976 |       : expected_successful_(expected_successful) {} | 
| Amin Hassani | 0cd9d77 | 2018-07-31 23:55:43 -0700 | [diff] [blame] | 977 |   bool ReceivedBytes(HttpFetcher* fetcher, | 
 | 978 |                      const void* bytes, | 
 | 979 |                      size_t length) override { | 
| Alex Vakulenko | f68bbbc | 2015-02-09 12:53:18 -0800 | [diff] [blame] | 980 |     data.append(reinterpret_cast<const char*>(bytes), length); | 
| Amin Hassani | 0cd9d77 | 2018-07-31 23:55:43 -0700 | [diff] [blame] | 981 |     return true; | 
| Darin Petkov | 41c2fcf | 2010-08-25 13:14:48 -0700 | [diff] [blame] | 982 |   } | 
| Alex Deymo | 610277e | 2014-11-11 21:18:11 -0800 | [diff] [blame] | 983 |   void TransferComplete(HttpFetcher* fetcher, bool successful) override { | 
| Darin Petkov | 41c2fcf | 2010-08-25 13:14:48 -0700 | [diff] [blame] | 984 |     EXPECT_EQ(expected_successful_, successful); | 
| Alex Vakulenko | d2779df | 2014-06-16 13:19:00 -0700 | [diff] [blame] | 985 |     if (expected_successful_) { | 
| Gilad Arnold | 9bedeb5 | 2011-11-17 16:19:57 -0800 | [diff] [blame] | 986 |       EXPECT_EQ(kHttpResponseOk, fetcher->http_response_code()); | 
| Alex Vakulenko | d2779df | 2014-06-16 13:19:00 -0700 | [diff] [blame] | 987 |     } else { | 
| Gilad Arnold | 9bedeb5 | 2011-11-17 16:19:57 -0800 | [diff] [blame] | 988 |       EXPECT_GE(fetcher->http_response_code(), kHttpResponseMovedPermanently); | 
 | 989 |       EXPECT_LE(fetcher->http_response_code(), kHttpResponseTempRedirect); | 
| Darin Petkov | cb46621 | 2010-08-26 09:40:11 -0700 | [diff] [blame] | 990 |     } | 
| Alex Deymo | 60ca1a7 | 2015-06-18 18:19:15 -0700 | [diff] [blame] | 991 |     MessageLoop::current()->BreakLoop(); | 
| Darin Petkov | 41c2fcf | 2010-08-25 13:14:48 -0700 | [diff] [blame] | 992 |   } | 
| Amin Hassani | b268959 | 2019-01-13 17:04:28 -0800 | [diff] [blame] | 993 |   void TransferTerminated(HttpFetcher* fetcher) override { ADD_FAILURE(); } | 
| Darin Petkov | 41c2fcf | 2010-08-25 13:14:48 -0700 | [diff] [blame] | 994 |   bool expected_successful_; | 
 | 995 |   string data; | 
| Darin Petkov | 41c2fcf | 2010-08-25 13:14:48 -0700 | [diff] [blame] | 996 | }; | 
 | 997 |  | 
 | 998 | // RedirectTest takes ownership of |http_fetcher|. | 
| Gilad Arnold | b6c562a | 2013-07-01 02:19:26 -0700 | [diff] [blame] | 999 | void RedirectTest(const HttpServer* server, | 
 | 1000 |                   bool expected_successful, | 
| Darin Petkov | 41c2fcf | 2010-08-25 13:14:48 -0700 | [diff] [blame] | 1001 |                   const string& url, | 
 | 1002 |                   HttpFetcher* http_fetcher) { | 
| Alex Deymo | 60ca1a7 | 2015-06-18 18:19:15 -0700 | [diff] [blame] | 1003 |   RedirectHttpFetcherTestDelegate delegate(expected_successful); | 
 | 1004 |   unique_ptr<HttpFetcher> fetcher(http_fetcher); | 
 | 1005 |   fetcher->set_delegate(&delegate); | 
| Darin Petkov | 41c2fcf | 2010-08-25 13:14:48 -0700 | [diff] [blame] | 1006 |  | 
| Amin Hassani | b268959 | 2019-01-13 17:04:28 -0800 | [diff] [blame] | 1007 |   MessageLoop::current()->PostTask( | 
 | 1008 |       FROM_HERE, | 
 | 1009 |       base::Bind(StartTransfer, | 
 | 1010 |                  fetcher.get(), | 
 | 1011 |                  LocalServerUrlForPath(server->GetPort(), url))); | 
| Alex Deymo | 60ca1a7 | 2015-06-18 18:19:15 -0700 | [diff] [blame] | 1012 |   MessageLoop::current()->Run(); | 
 | 1013 |   if (expected_successful) { | 
 | 1014 |     // verify the data we get back | 
| Alex Deymo | 80f70ff | 2016-02-10 16:08:11 -0800 | [diff] [blame] | 1015 |     ASSERT_EQ(static_cast<size_t>(kMediumLength), delegate.data.size()); | 
| Alex Deymo | 60ca1a7 | 2015-06-18 18:19:15 -0700 | [diff] [blame] | 1016 |     for (int i = 0; i < kMediumLength; i += 10) { | 
 | 1017 |       // Assert so that we don't flood the screen w/ EXPECT errors on failure. | 
 | 1018 |       ASSERT_EQ(delegate.data.substr(i, 10), "abcdefghij"); | 
| Darin Petkov | 41c2fcf | 2010-08-25 13:14:48 -0700 | [diff] [blame] | 1019 |     } | 
 | 1020 |   } | 
| Darin Petkov | 41c2fcf | 2010-08-25 13:14:48 -0700 | [diff] [blame] | 1021 | } | 
| Darin Petkov | 41c2fcf | 2010-08-25 13:14:48 -0700 | [diff] [blame] | 1022 |  | 
 | 1023 | TYPED_TEST(HttpFetcherTest, SimpleRedirectTest) { | 
| Alex Deymo | 2c131bb | 2016-05-26 16:43:13 -0700 | [diff] [blame] | 1024 |   if (this->test_.IsMock() || !this->test_.IsHttpSupported()) | 
| Darin Petkov | 41c2fcf | 2010-08-25 13:14:48 -0700 | [diff] [blame] | 1025 |     return; | 
| Gilad Arnold | 9bedeb5 | 2011-11-17 16:19:57 -0800 | [diff] [blame] | 1026 |  | 
| Ben Chan | 02f7c1d | 2014-10-18 15:18:02 -0700 | [diff] [blame] | 1027 |   unique_ptr<HttpServer> server(this->test_.CreateServer()); | 
| Gilad Arnold | 9bedeb5 | 2011-11-17 16:19:57 -0800 | [diff] [blame] | 1028 |   ASSERT_TRUE(server->started_); | 
 | 1029 |  | 
| hscham | 00b6aa2 | 2020-02-20 12:32:06 +0900 | [diff] [blame] | 1030 |   for (size_t c = 0; c < base::size(kRedirectCodes); ++c) { | 
| Amin Hassani | b268959 | 2019-01-13 17:04:28 -0800 | [diff] [blame] | 1031 |     const string url = base::StringPrintf( | 
 | 1032 |         "/redirect/%d/download/%d", kRedirectCodes[c], kMediumLength); | 
| Gilad Arnold | b6c562a | 2013-07-01 02:19:26 -0700 | [diff] [blame] | 1033 |     RedirectTest(server.get(), true, url, this->test_.NewLargeFetcher()); | 
| Darin Petkov | 41c2fcf | 2010-08-25 13:14:48 -0700 | [diff] [blame] | 1034 |   } | 
 | 1035 | } | 
 | 1036 |  | 
 | 1037 | TYPED_TEST(HttpFetcherTest, MaxRedirectTest) { | 
| Alex Deymo | 2c131bb | 2016-05-26 16:43:13 -0700 | [diff] [blame] | 1038 |   if (this->test_.IsMock() || !this->test_.IsHttpSupported()) | 
| Darin Petkov | 41c2fcf | 2010-08-25 13:14:48 -0700 | [diff] [blame] | 1039 |     return; | 
| Gilad Arnold | 9bedeb5 | 2011-11-17 16:19:57 -0800 | [diff] [blame] | 1040 |  | 
| Ben Chan | 02f7c1d | 2014-10-18 15:18:02 -0700 | [diff] [blame] | 1041 |   unique_ptr<HttpServer> server(this->test_.CreateServer()); | 
| Gilad Arnold | 9bedeb5 | 2011-11-17 16:19:57 -0800 | [diff] [blame] | 1042 |   ASSERT_TRUE(server->started_); | 
 | 1043 |  | 
| Darin Petkov | 41c2fcf | 2010-08-25 13:14:48 -0700 | [diff] [blame] | 1044 |   string url; | 
| David Zeuthen | 34135a9 | 2013-08-06 11:16:16 -0700 | [diff] [blame] | 1045 |   for (int r = 0; r < kDownloadMaxRedirects; r++) { | 
| Darin Petkov | 41c2fcf | 2010-08-25 13:14:48 -0700 | [diff] [blame] | 1046 |     url += base::StringPrintf("/redirect/%d", | 
| hscham | 00b6aa2 | 2020-02-20 12:32:06 +0900 | [diff] [blame] | 1047 |                               kRedirectCodes[r % base::size(kRedirectCodes)]); | 
| Darin Petkov | 41c2fcf | 2010-08-25 13:14:48 -0700 | [diff] [blame] | 1048 |   } | 
| Gilad Arnold | 9bedeb5 | 2011-11-17 16:19:57 -0800 | [diff] [blame] | 1049 |   url += base::StringPrintf("/download/%d", kMediumLength); | 
| Gilad Arnold | b6c562a | 2013-07-01 02:19:26 -0700 | [diff] [blame] | 1050 |   RedirectTest(server.get(), true, url, this->test_.NewLargeFetcher()); | 
| Darin Petkov | 41c2fcf | 2010-08-25 13:14:48 -0700 | [diff] [blame] | 1051 | } | 
 | 1052 |  | 
 | 1053 | TYPED_TEST(HttpFetcherTest, BeyondMaxRedirectTest) { | 
| Alex Deymo | 2c131bb | 2016-05-26 16:43:13 -0700 | [diff] [blame] | 1054 |   if (this->test_.IsMock() || !this->test_.IsHttpSupported()) | 
| Darin Petkov | 41c2fcf | 2010-08-25 13:14:48 -0700 | [diff] [blame] | 1055 |     return; | 
| Gilad Arnold | 9bedeb5 | 2011-11-17 16:19:57 -0800 | [diff] [blame] | 1056 |  | 
| Ben Chan | 02f7c1d | 2014-10-18 15:18:02 -0700 | [diff] [blame] | 1057 |   unique_ptr<HttpServer> server(this->test_.CreateServer()); | 
| Gilad Arnold | 9bedeb5 | 2011-11-17 16:19:57 -0800 | [diff] [blame] | 1058 |   ASSERT_TRUE(server->started_); | 
 | 1059 |  | 
| Darin Petkov | 41c2fcf | 2010-08-25 13:14:48 -0700 | [diff] [blame] | 1060 |   string url; | 
| David Zeuthen | 34135a9 | 2013-08-06 11:16:16 -0700 | [diff] [blame] | 1061 |   for (int r = 0; r < kDownloadMaxRedirects + 1; r++) { | 
| Darin Petkov | 41c2fcf | 2010-08-25 13:14:48 -0700 | [diff] [blame] | 1062 |     url += base::StringPrintf("/redirect/%d", | 
| hscham | 00b6aa2 | 2020-02-20 12:32:06 +0900 | [diff] [blame] | 1063 |                               kRedirectCodes[r % base::size(kRedirectCodes)]); | 
| Darin Petkov | 41c2fcf | 2010-08-25 13:14:48 -0700 | [diff] [blame] | 1064 |   } | 
| Gilad Arnold | 9bedeb5 | 2011-11-17 16:19:57 -0800 | [diff] [blame] | 1065 |   url += base::StringPrintf("/download/%d", kMediumLength); | 
| Gilad Arnold | b6c562a | 2013-07-01 02:19:26 -0700 | [diff] [blame] | 1066 |   RedirectTest(server.get(), false, url, this->test_.NewLargeFetcher()); | 
| Darin Petkov | 41c2fcf | 2010-08-25 13:14:48 -0700 | [diff] [blame] | 1067 | } | 
 | 1068 |  | 
| Andrew de los Reyes | 3fd5d30 | 2010-10-07 20:07:18 -0700 | [diff] [blame] | 1069 | class MultiHttpFetcherTestDelegate : public HttpFetcherDelegate { | 
 | 1070 |  public: | 
| Alex Vakulenko | d2779df | 2014-06-16 13:19:00 -0700 | [diff] [blame] | 1071 |   explicit MultiHttpFetcherTestDelegate(int expected_response_code) | 
| Andrew de los Reyes | 3fd5d30 | 2010-10-07 20:07:18 -0700 | [diff] [blame] | 1072 |       : expected_response_code_(expected_response_code) {} | 
| Gilad Arnold | e4ad250 | 2011-12-29 17:08:54 -0800 | [diff] [blame] | 1073 |  | 
| Amin Hassani | 0cd9d77 | 2018-07-31 23:55:43 -0700 | [diff] [blame] | 1074 |   bool ReceivedBytes(HttpFetcher* fetcher, | 
 | 1075 |                      const void* bytes, | 
 | 1076 |                      size_t length) override { | 
| Darin Petkov | 9ce452b | 2010-11-17 14:33:28 -0800 | [diff] [blame] | 1077 |     EXPECT_EQ(fetcher, fetcher_.get()); | 
| Alex Vakulenko | f68bbbc | 2015-02-09 12:53:18 -0800 | [diff] [blame] | 1078 |     data.append(reinterpret_cast<const char*>(bytes), length); | 
| Amin Hassani | 0cd9d77 | 2018-07-31 23:55:43 -0700 | [diff] [blame] | 1079 |     return true; | 
| Andrew de los Reyes | 3fd5d30 | 2010-10-07 20:07:18 -0700 | [diff] [blame] | 1080 |   } | 
| Gilad Arnold | e4ad250 | 2011-12-29 17:08:54 -0800 | [diff] [blame] | 1081 |  | 
| Alex Deymo | 610277e | 2014-11-11 21:18:11 -0800 | [diff] [blame] | 1082 |   void TransferComplete(HttpFetcher* fetcher, bool successful) override { | 
| Darin Petkov | 9ce452b | 2010-11-17 14:33:28 -0800 | [diff] [blame] | 1083 |     EXPECT_EQ(fetcher, fetcher_.get()); | 
| Gilad Arnold | 9bedeb5 | 2011-11-17 16:19:57 -0800 | [diff] [blame] | 1084 |     EXPECT_EQ(expected_response_code_ != kHttpResponseUndefined, successful); | 
| Andrew de los Reyes | 3fd5d30 | 2010-10-07 20:07:18 -0700 | [diff] [blame] | 1085 |     if (expected_response_code_ != 0) | 
 | 1086 |       EXPECT_EQ(expected_response_code_, fetcher->http_response_code()); | 
| Darin Petkov | 9ce452b | 2010-11-17 14:33:28 -0800 | [diff] [blame] | 1087 |     // Destroy the fetcher (because we're allowed to). | 
| Alex Vakulenko | 88b591f | 2014-08-28 16:48:57 -0700 | [diff] [blame] | 1088 |     fetcher_.reset(nullptr); | 
| Alex Deymo | 60ca1a7 | 2015-06-18 18:19:15 -0700 | [diff] [blame] | 1089 |     MessageLoop::current()->BreakLoop(); | 
| Andrew de los Reyes | 3fd5d30 | 2010-10-07 20:07:18 -0700 | [diff] [blame] | 1090 |   } | 
| Gilad Arnold | e4ad250 | 2011-12-29 17:08:54 -0800 | [diff] [blame] | 1091 |  | 
| Amin Hassani | b268959 | 2019-01-13 17:04:28 -0800 | [diff] [blame] | 1092 |   void TransferTerminated(HttpFetcher* fetcher) override { ADD_FAILURE(); } | 
| Gilad Arnold | e4ad250 | 2011-12-29 17:08:54 -0800 | [diff] [blame] | 1093 |  | 
| Ben Chan | 02f7c1d | 2014-10-18 15:18:02 -0700 | [diff] [blame] | 1094 |   unique_ptr<HttpFetcher> fetcher_; | 
| Andrew de los Reyes | 3fd5d30 | 2010-10-07 20:07:18 -0700 | [diff] [blame] | 1095 |   int expected_response_code_; | 
 | 1096 |   string data; | 
| Andrew de los Reyes | 3fd5d30 | 2010-10-07 20:07:18 -0700 | [diff] [blame] | 1097 | }; | 
 | 1098 |  | 
 | 1099 | void MultiTest(HttpFetcher* fetcher_in, | 
| Alex Deymo | c1c17b4 | 2015-11-23 03:53:15 -0300 | [diff] [blame] | 1100 |                FakeHardware* fake_hardware, | 
| Andrew de los Reyes | 3fd5d30 | 2010-10-07 20:07:18 -0700 | [diff] [blame] | 1101 |                const string& url, | 
| Ben Chan | f9cb98c | 2014-09-21 18:31:30 -0700 | [diff] [blame] | 1102 |                const vector<pair<off_t, off_t>>& ranges, | 
| Andrew de los Reyes | 3fd5d30 | 2010-10-07 20:07:18 -0700 | [diff] [blame] | 1103 |                const string& expected_prefix, | 
| Alex Deymo | 5fe0c4e | 2016-02-16 18:46:24 -0800 | [diff] [blame] | 1104 |                size_t expected_size, | 
| Gilad Arnold | 9bedeb5 | 2011-11-17 16:19:57 -0800 | [diff] [blame] | 1105 |                HttpResponseCode expected_response_code) { | 
| Alex Deymo | 60ca1a7 | 2015-06-18 18:19:15 -0700 | [diff] [blame] | 1106 |   MultiHttpFetcherTestDelegate delegate(expected_response_code); | 
 | 1107 |   delegate.fetcher_.reset(fetcher_in); | 
| Jay Srinivasan | 4348879 | 2012-06-19 00:25:31 -0700 | [diff] [blame] | 1108 |  | 
| Alex Deymo | 60ca1a7 | 2015-06-18 18:19:15 -0700 | [diff] [blame] | 1109 |   MultiRangeHttpFetcher* multi_fetcher = | 
| Alex Deymo | 80f70ff | 2016-02-10 16:08:11 -0800 | [diff] [blame] | 1110 |       static_cast<MultiRangeHttpFetcher*>(fetcher_in); | 
| Alex Deymo | 60ca1a7 | 2015-06-18 18:19:15 -0700 | [diff] [blame] | 1111 |   ASSERT_TRUE(multi_fetcher); | 
 | 1112 |   multi_fetcher->ClearRanges(); | 
 | 1113 |   for (vector<pair<off_t, off_t>>::const_iterator it = ranges.begin(), | 
| Amin Hassani | b268959 | 2019-01-13 17:04:28 -0800 | [diff] [blame] | 1114 |                                                   e = ranges.end(); | 
 | 1115 |        it != e; | 
 | 1116 |        ++it) { | 
| Alex Deymo | 60ca1a7 | 2015-06-18 18:19:15 -0700 | [diff] [blame] | 1117 |     string tmp_str = base::StringPrintf("%jd+", it->first); | 
 | 1118 |     if (it->second > 0) { | 
 | 1119 |       base::StringAppendF(&tmp_str, "%jd", it->second); | 
 | 1120 |       multi_fetcher->AddRange(it->first, it->second); | 
 | 1121 |     } else { | 
 | 1122 |       base::StringAppendF(&tmp_str, "?"); | 
 | 1123 |       multi_fetcher->AddRange(it->first); | 
| Andrew de los Reyes | 819fef2 | 2010-12-17 11:33:58 -0800 | [diff] [blame] | 1124 |     } | 
| Alex Deymo | 60ca1a7 | 2015-06-18 18:19:15 -0700 | [diff] [blame] | 1125 |     LOG(INFO) << "added range: " << tmp_str; | 
| Andrew de los Reyes | 3fd5d30 | 2010-10-07 20:07:18 -0700 | [diff] [blame] | 1126 |   } | 
| Alex Deymo | c1c17b4 | 2015-11-23 03:53:15 -0300 | [diff] [blame] | 1127 |   fake_hardware->SetIsOfficialBuild(false); | 
| Alex Deymo | 60ca1a7 | 2015-06-18 18:19:15 -0700 | [diff] [blame] | 1128 |   multi_fetcher->set_delegate(&delegate); | 
 | 1129 |  | 
 | 1130 |   MessageLoop::current()->PostTask( | 
| Amin Hassani | b268959 | 2019-01-13 17:04:28 -0800 | [diff] [blame] | 1131 |       FROM_HERE, base::Bind(StartTransfer, multi_fetcher, url)); | 
| Alex Deymo | 60ca1a7 | 2015-06-18 18:19:15 -0700 | [diff] [blame] | 1132 |   MessageLoop::current()->Run(); | 
 | 1133 |  | 
 | 1134 |   EXPECT_EQ(expected_size, delegate.data.size()); | 
 | 1135 |   EXPECT_EQ(expected_prefix, | 
 | 1136 |             string(delegate.data.data(), expected_prefix.size())); | 
| Andrew de los Reyes | 3fd5d30 | 2010-10-07 20:07:18 -0700 | [diff] [blame] | 1137 | } | 
| Andrew de los Reyes | 3fd5d30 | 2010-10-07 20:07:18 -0700 | [diff] [blame] | 1138 |  | 
| Darin Petkov | 9ce452b | 2010-11-17 14:33:28 -0800 | [diff] [blame] | 1139 | TYPED_TEST(HttpFetcherTest, MultiHttpFetcherSimpleTest) { | 
| Gilad Arnold | 9bedeb5 | 2011-11-17 16:19:57 -0800 | [diff] [blame] | 1140 |   if (!this->test_.IsMulti()) | 
| Andrew de los Reyes | 3fd5d30 | 2010-10-07 20:07:18 -0700 | [diff] [blame] | 1141 |     return; | 
| Gilad Arnold | 9bedeb5 | 2011-11-17 16:19:57 -0800 | [diff] [blame] | 1142 |  | 
| Ben Chan | 02f7c1d | 2014-10-18 15:18:02 -0700 | [diff] [blame] | 1143 |   unique_ptr<HttpServer> server(this->test_.CreateServer()); | 
| Gilad Arnold | 9bedeb5 | 2011-11-17 16:19:57 -0800 | [diff] [blame] | 1144 |   ASSERT_TRUE(server->started_); | 
| Andrew de los Reyes | 3fd5d30 | 2010-10-07 20:07:18 -0700 | [diff] [blame] | 1145 |  | 
| Ben Chan | f9cb98c | 2014-09-21 18:31:30 -0700 | [diff] [blame] | 1146 |   vector<pair<off_t, off_t>> ranges; | 
| Andrew de los Reyes | 3fd5d30 | 2010-10-07 20:07:18 -0700 | [diff] [blame] | 1147 |   ranges.push_back(make_pair(0, 25)); | 
| Tao Bao | 642b32b | 2019-01-02 15:33:42 -0800 | [diff] [blame] | 1148 |   ranges.push_back(make_pair(99, 17)); | 
 | 1149 |   MultiTest(this->test_.NewLargeFetcher(), | 
 | 1150 |             this->test_.fake_hardware(), | 
 | 1151 |             this->test_.BigUrl(server->GetPort()), | 
 | 1152 |             ranges, | 
 | 1153 |             "abcdefghijabcdefghijabcdejabcdefghijabcdef", | 
 | 1154 |             25 + 17, | 
 | 1155 |             this->test_.IsFileFetcher() ? kHttpResponseOk | 
 | 1156 |                                         : kHttpResponsePartialContent); | 
 | 1157 | } | 
 | 1158 |  | 
 | 1159 | TYPED_TEST(HttpFetcherTest, MultiHttpFetcherUnspecifiedEndTest) { | 
 | 1160 |   if (!this->test_.IsMulti() || this->test_.IsFileFetcher()) | 
 | 1161 |     return; | 
 | 1162 |  | 
 | 1163 |   unique_ptr<HttpServer> server(this->test_.CreateServer()); | 
 | 1164 |   ASSERT_TRUE(server->started_); | 
 | 1165 |  | 
 | 1166 |   vector<pair<off_t, off_t>> ranges; | 
 | 1167 |   ranges.push_back(make_pair(0, 25)); | 
| Gilad Arnold | e4ad250 | 2011-12-29 17:08:54 -0800 | [diff] [blame] | 1168 |   ranges.push_back(make_pair(99, 0)); | 
| Gilad Arnold | 9bedeb5 | 2011-11-17 16:19:57 -0800 | [diff] [blame] | 1169 |   MultiTest(this->test_.NewLargeFetcher(), | 
| Alex Deymo | c1c17b4 | 2015-11-23 03:53:15 -0300 | [diff] [blame] | 1170 |             this->test_.fake_hardware(), | 
| Gilad Arnold | b6c562a | 2013-07-01 02:19:26 -0700 | [diff] [blame] | 1171 |             this->test_.BigUrl(server->GetPort()), | 
| Andrew de los Reyes | 3fd5d30 | 2010-10-07 20:07:18 -0700 | [diff] [blame] | 1172 |             ranges, | 
 | 1173 |             "abcdefghijabcdefghijabcdejabcdefghijabcdef", | 
| Gilad Arnold | 9bedeb5 | 2011-11-17 16:19:57 -0800 | [diff] [blame] | 1174 |             kBigLength - (99 - 25), | 
 | 1175 |             kHttpResponsePartialContent); | 
| Andrew de los Reyes | 3fd5d30 | 2010-10-07 20:07:18 -0700 | [diff] [blame] | 1176 | } | 
 | 1177 |  | 
 | 1178 | TYPED_TEST(HttpFetcherTest, MultiHttpFetcherLengthLimitTest) { | 
| Gilad Arnold | 9bedeb5 | 2011-11-17 16:19:57 -0800 | [diff] [blame] | 1179 |   if (!this->test_.IsMulti()) | 
| Andrew de los Reyes | 3fd5d30 | 2010-10-07 20:07:18 -0700 | [diff] [blame] | 1180 |     return; | 
| Gilad Arnold | 9bedeb5 | 2011-11-17 16:19:57 -0800 | [diff] [blame] | 1181 |  | 
| Ben Chan | 02f7c1d | 2014-10-18 15:18:02 -0700 | [diff] [blame] | 1182 |   unique_ptr<HttpServer> server(this->test_.CreateServer()); | 
| Gilad Arnold | 9bedeb5 | 2011-11-17 16:19:57 -0800 | [diff] [blame] | 1183 |   ASSERT_TRUE(server->started_); | 
| Andrew de los Reyes | 3fd5d30 | 2010-10-07 20:07:18 -0700 | [diff] [blame] | 1184 |  | 
| Ben Chan | f9cb98c | 2014-09-21 18:31:30 -0700 | [diff] [blame] | 1185 |   vector<pair<off_t, off_t>> ranges; | 
| Andrew de los Reyes | 3fd5d30 | 2010-10-07 20:07:18 -0700 | [diff] [blame] | 1186 |   ranges.push_back(make_pair(0, 24)); | 
| Gilad Arnold | 9bedeb5 | 2011-11-17 16:19:57 -0800 | [diff] [blame] | 1187 |   MultiTest(this->test_.NewLargeFetcher(), | 
| Alex Deymo | c1c17b4 | 2015-11-23 03:53:15 -0300 | [diff] [blame] | 1188 |             this->test_.fake_hardware(), | 
| Gilad Arnold | b6c562a | 2013-07-01 02:19:26 -0700 | [diff] [blame] | 1189 |             this->test_.BigUrl(server->GetPort()), | 
| Andrew de los Reyes | 3fd5d30 | 2010-10-07 20:07:18 -0700 | [diff] [blame] | 1190 |             ranges, | 
 | 1191 |             "abcdefghijabcdefghijabcd", | 
 | 1192 |             24, | 
| Tao Bao | 642b32b | 2019-01-02 15:33:42 -0800 | [diff] [blame] | 1193 |             this->test_.IsFileFetcher() ? kHttpResponseOk | 
 | 1194 |                                         : kHttpResponsePartialContent); | 
| Andrew de los Reyes | 3fd5d30 | 2010-10-07 20:07:18 -0700 | [diff] [blame] | 1195 | } | 
 | 1196 |  | 
 | 1197 | TYPED_TEST(HttpFetcherTest, MultiHttpFetcherMultiEndTest) { | 
| Tao Bao | 642b32b | 2019-01-02 15:33:42 -0800 | [diff] [blame] | 1198 |   if (!this->test_.IsMulti() || this->test_.IsFileFetcher()) | 
| Andrew de los Reyes | 3fd5d30 | 2010-10-07 20:07:18 -0700 | [diff] [blame] | 1199 |     return; | 
| Gilad Arnold | 9bedeb5 | 2011-11-17 16:19:57 -0800 | [diff] [blame] | 1200 |  | 
| Ben Chan | 02f7c1d | 2014-10-18 15:18:02 -0700 | [diff] [blame] | 1201 |   unique_ptr<HttpServer> server(this->test_.CreateServer()); | 
| Gilad Arnold | 9bedeb5 | 2011-11-17 16:19:57 -0800 | [diff] [blame] | 1202 |   ASSERT_TRUE(server->started_); | 
| Andrew de los Reyes | 3fd5d30 | 2010-10-07 20:07:18 -0700 | [diff] [blame] | 1203 |  | 
| Ben Chan | f9cb98c | 2014-09-21 18:31:30 -0700 | [diff] [blame] | 1204 |   vector<pair<off_t, off_t>> ranges; | 
| Gilad Arnold | e4ad250 | 2011-12-29 17:08:54 -0800 | [diff] [blame] | 1205 |   ranges.push_back(make_pair(kBigLength - 2, 0)); | 
 | 1206 |   ranges.push_back(make_pair(kBigLength - 3, 0)); | 
| Gilad Arnold | 9bedeb5 | 2011-11-17 16:19:57 -0800 | [diff] [blame] | 1207 |   MultiTest(this->test_.NewLargeFetcher(), | 
| Alex Deymo | c1c17b4 | 2015-11-23 03:53:15 -0300 | [diff] [blame] | 1208 |             this->test_.fake_hardware(), | 
| Gilad Arnold | b6c562a | 2013-07-01 02:19:26 -0700 | [diff] [blame] | 1209 |             this->test_.BigUrl(server->GetPort()), | 
| Andrew de los Reyes | 3fd5d30 | 2010-10-07 20:07:18 -0700 | [diff] [blame] | 1210 |             ranges, | 
 | 1211 |             "ijhij", | 
 | 1212 |             5, | 
| Gilad Arnold | 9bedeb5 | 2011-11-17 16:19:57 -0800 | [diff] [blame] | 1213 |             kHttpResponsePartialContent); | 
| Andrew de los Reyes | 3fd5d30 | 2010-10-07 20:07:18 -0700 | [diff] [blame] | 1214 | } | 
 | 1215 |  | 
 | 1216 | TYPED_TEST(HttpFetcherTest, MultiHttpFetcherInsufficientTest) { | 
| Gilad Arnold | 9bedeb5 | 2011-11-17 16:19:57 -0800 | [diff] [blame] | 1217 |   if (!this->test_.IsMulti()) | 
| Andrew de los Reyes | 3fd5d30 | 2010-10-07 20:07:18 -0700 | [diff] [blame] | 1218 |     return; | 
| Gilad Arnold | 9bedeb5 | 2011-11-17 16:19:57 -0800 | [diff] [blame] | 1219 |  | 
| Ben Chan | 02f7c1d | 2014-10-18 15:18:02 -0700 | [diff] [blame] | 1220 |   unique_ptr<HttpServer> server(this->test_.CreateServer()); | 
| Gilad Arnold | 9bedeb5 | 2011-11-17 16:19:57 -0800 | [diff] [blame] | 1221 |   ASSERT_TRUE(server->started_); | 
| Andrew de los Reyes | 3fd5d30 | 2010-10-07 20:07:18 -0700 | [diff] [blame] | 1222 |  | 
| Ben Chan | f9cb98c | 2014-09-21 18:31:30 -0700 | [diff] [blame] | 1223 |   vector<pair<off_t, off_t>> ranges; | 
| Gilad Arnold | 9bedeb5 | 2011-11-17 16:19:57 -0800 | [diff] [blame] | 1224 |   ranges.push_back(make_pair(kBigLength - 2, 4)); | 
| Andrew de los Reyes | 3fd5d30 | 2010-10-07 20:07:18 -0700 | [diff] [blame] | 1225 |   for (int i = 0; i < 2; ++i) { | 
| Andrew de los Reyes | 819fef2 | 2010-12-17 11:33:58 -0800 | [diff] [blame] | 1226 |     LOG(INFO) << "i = " << i; | 
| Gilad Arnold | 9bedeb5 | 2011-11-17 16:19:57 -0800 | [diff] [blame] | 1227 |     MultiTest(this->test_.NewLargeFetcher(), | 
| Alex Deymo | c1c17b4 | 2015-11-23 03:53:15 -0300 | [diff] [blame] | 1228 |               this->test_.fake_hardware(), | 
| Gilad Arnold | b6c562a | 2013-07-01 02:19:26 -0700 | [diff] [blame] | 1229 |               this->test_.BigUrl(server->GetPort()), | 
| Andrew de los Reyes | 3fd5d30 | 2010-10-07 20:07:18 -0700 | [diff] [blame] | 1230 |               ranges, | 
 | 1231 |               "ij", | 
 | 1232 |               2, | 
| Gilad Arnold | 9bedeb5 | 2011-11-17 16:19:57 -0800 | [diff] [blame] | 1233 |               kHttpResponseUndefined); | 
| Andrew de los Reyes | 3fd5d30 | 2010-10-07 20:07:18 -0700 | [diff] [blame] | 1234 |     ranges.push_back(make_pair(0, 5)); | 
 | 1235 |   } | 
 | 1236 | } | 
 | 1237 |  | 
| Gilad Arnold | 9bedeb5 | 2011-11-17 16:19:57 -0800 | [diff] [blame] | 1238 | // Issue #18143: when a fetch of a secondary chunk out of a chain, then it | 
 | 1239 | // should retry with other proxies listed before giving up. | 
 | 1240 | // | 
 | 1241 | // (1) successful recovery: The offset fetch will fail twice but succeed with | 
 | 1242 | // the third proxy. | 
 | 1243 | TYPED_TEST(HttpFetcherTest, MultiHttpFetcherErrorIfOffsetRecoverableTest) { | 
| Tao Bao | 642b32b | 2019-01-02 15:33:42 -0800 | [diff] [blame] | 1244 |   if (!this->test_.IsMulti() || this->test_.IsFileFetcher()) | 
| Gilad Arnold | 9bedeb5 | 2011-11-17 16:19:57 -0800 | [diff] [blame] | 1245 |     return; | 
 | 1246 |  | 
| Ben Chan | 02f7c1d | 2014-10-18 15:18:02 -0700 | [diff] [blame] | 1247 |   unique_ptr<HttpServer> server(this->test_.CreateServer()); | 
| Gilad Arnold | 9bedeb5 | 2011-11-17 16:19:57 -0800 | [diff] [blame] | 1248 |   ASSERT_TRUE(server->started_); | 
 | 1249 |  | 
| Ben Chan | f9cb98c | 2014-09-21 18:31:30 -0700 | [diff] [blame] | 1250 |   vector<pair<off_t, off_t>> ranges; | 
| Gilad Arnold | 9bedeb5 | 2011-11-17 16:19:57 -0800 | [diff] [blame] | 1251 |   ranges.push_back(make_pair(0, 25)); | 
| Gilad Arnold | e4ad250 | 2011-12-29 17:08:54 -0800 | [diff] [blame] | 1252 |   ranges.push_back(make_pair(99, 0)); | 
| Gilad Arnold | 9bedeb5 | 2011-11-17 16:19:57 -0800 | [diff] [blame] | 1253 |   MultiTest(this->test_.NewLargeFetcher(3), | 
| Alex Deymo | c1c17b4 | 2015-11-23 03:53:15 -0300 | [diff] [blame] | 1254 |             this->test_.fake_hardware(), | 
| Amin Hassani | b268959 | 2019-01-13 17:04:28 -0800 | [diff] [blame] | 1255 |             LocalServerUrlForPath( | 
 | 1256 |                 server->GetPort(), | 
 | 1257 |                 base::StringPrintf("/error-if-offset/%d/2", kBigLength)), | 
| Gilad Arnold | 9bedeb5 | 2011-11-17 16:19:57 -0800 | [diff] [blame] | 1258 |             ranges, | 
 | 1259 |             "abcdefghijabcdefghijabcdejabcdefghijabcdef", | 
 | 1260 |             kBigLength - (99 - 25), | 
 | 1261 |             kHttpResponsePartialContent); | 
 | 1262 | } | 
 | 1263 |  | 
 | 1264 | // (2) unsuccessful recovery: The offset fetch will fail repeatedly.  The | 
 | 1265 | // fetcher will signal a (failed) completed transfer to the delegate. | 
 | 1266 | TYPED_TEST(HttpFetcherTest, MultiHttpFetcherErrorIfOffsetUnrecoverableTest) { | 
| Tao Bao | 642b32b | 2019-01-02 15:33:42 -0800 | [diff] [blame] | 1267 |   if (!this->test_.IsMulti() || this->test_.IsFileFetcher()) | 
| Gilad Arnold | 9bedeb5 | 2011-11-17 16:19:57 -0800 | [diff] [blame] | 1268 |     return; | 
 | 1269 |  | 
| Ben Chan | 02f7c1d | 2014-10-18 15:18:02 -0700 | [diff] [blame] | 1270 |   unique_ptr<HttpServer> server(this->test_.CreateServer()); | 
| Gilad Arnold | 9bedeb5 | 2011-11-17 16:19:57 -0800 | [diff] [blame] | 1271 |   ASSERT_TRUE(server->started_); | 
 | 1272 |  | 
| Ben Chan | f9cb98c | 2014-09-21 18:31:30 -0700 | [diff] [blame] | 1273 |   vector<pair<off_t, off_t>> ranges; | 
| Gilad Arnold | 9bedeb5 | 2011-11-17 16:19:57 -0800 | [diff] [blame] | 1274 |   ranges.push_back(make_pair(0, 25)); | 
| Gilad Arnold | e4ad250 | 2011-12-29 17:08:54 -0800 | [diff] [blame] | 1275 |   ranges.push_back(make_pair(99, 0)); | 
| Kelvin Zhang | c7a1d1f | 2022-07-29 13:36:29 -0700 | [diff] [blame] | 1276 |   MultiTest(this->test_.NewLargeFetcher(), | 
| Alex Deymo | c1c17b4 | 2015-11-23 03:53:15 -0300 | [diff] [blame] | 1277 |             this->test_.fake_hardware(), | 
| Amin Hassani | b268959 | 2019-01-13 17:04:28 -0800 | [diff] [blame] | 1278 |             LocalServerUrlForPath( | 
 | 1279 |                 server->GetPort(), | 
 | 1280 |                 base::StringPrintf("/error-if-offset/%d/3", kBigLength)), | 
| Gilad Arnold | 9bedeb5 | 2011-11-17 16:19:57 -0800 | [diff] [blame] | 1281 |             ranges, | 
 | 1282 |             "abcdefghijabcdefghijabcde",  // only received the first chunk | 
 | 1283 |             25, | 
 | 1284 |             kHttpResponseUndefined); | 
 | 1285 | } | 
 | 1286 |  | 
| Alex Deymo | 4ea2d92 | 2017-02-05 07:35:32 +0000 | [diff] [blame] | 1287 | // This HttpFetcherDelegate calls TerminateTransfer at a configurable point. | 
 | 1288 | class MultiHttpFetcherTerminateTestDelegate : public HttpFetcherDelegate { | 
 | 1289 |  public: | 
 | 1290 |   explicit MultiHttpFetcherTerminateTestDelegate(size_t terminate_trigger_bytes) | 
 | 1291 |       : terminate_trigger_bytes_(terminate_trigger_bytes) {} | 
| Gilad Arnold | 9bedeb5 | 2011-11-17 16:19:57 -0800 | [diff] [blame] | 1292 |  | 
| Amin Hassani | 0cd9d77 | 2018-07-31 23:55:43 -0700 | [diff] [blame] | 1293 |   bool ReceivedBytes(HttpFetcher* fetcher, | 
| Alex Deymo | 4ea2d92 | 2017-02-05 07:35:32 +0000 | [diff] [blame] | 1294 |                      const void* bytes, | 
 | 1295 |                      size_t length) override { | 
 | 1296 |     LOG(INFO) << "ReceivedBytes, " << length << " bytes."; | 
 | 1297 |     EXPECT_EQ(fetcher, fetcher_.get()); | 
| Tao Bao | 642b32b | 2019-01-02 15:33:42 -0800 | [diff] [blame] | 1298 |     bool should_terminate = false; | 
| Alex Deymo | 4ea2d92 | 2017-02-05 07:35:32 +0000 | [diff] [blame] | 1299 |     if (bytes_downloaded_ < terminate_trigger_bytes_ && | 
 | 1300 |         bytes_downloaded_ + length >= terminate_trigger_bytes_) { | 
 | 1301 |       MessageLoop::current()->PostTask( | 
 | 1302 |           FROM_HERE, | 
 | 1303 |           base::Bind(&HttpFetcher::TerminateTransfer, | 
 | 1304 |                      base::Unretained(fetcher_.get()))); | 
| Tao Bao | 642b32b | 2019-01-02 15:33:42 -0800 | [diff] [blame] | 1305 |       should_terminate = true; | 
| Alex Deymo | 4ea2d92 | 2017-02-05 07:35:32 +0000 | [diff] [blame] | 1306 |     } | 
 | 1307 |     bytes_downloaded_ += length; | 
| Tao Bao | 642b32b | 2019-01-02 15:33:42 -0800 | [diff] [blame] | 1308 |     return !should_terminate; | 
| Alex Deymo | 4ea2d92 | 2017-02-05 07:35:32 +0000 | [diff] [blame] | 1309 |   } | 
 | 1310 |  | 
 | 1311 |   void TransferComplete(HttpFetcher* fetcher, bool successful) override { | 
 | 1312 |     ADD_FAILURE() << "TransferComplete called but expected a failure"; | 
 | 1313 |     // Destroy the fetcher (because we're allowed to). | 
 | 1314 |     fetcher_.reset(nullptr); | 
 | 1315 |     MessageLoop::current()->BreakLoop(); | 
 | 1316 |   } | 
 | 1317 |  | 
 | 1318 |   void TransferTerminated(HttpFetcher* fetcher) override { | 
 | 1319 |     // Destroy the fetcher (because we're allowed to). | 
 | 1320 |     fetcher_.reset(nullptr); | 
 | 1321 |     MessageLoop::current()->BreakLoop(); | 
 | 1322 |   } | 
 | 1323 |  | 
 | 1324 |   unique_ptr<HttpFetcher> fetcher_; | 
 | 1325 |   size_t bytes_downloaded_{0}; | 
 | 1326 |   size_t terminate_trigger_bytes_; | 
 | 1327 | }; | 
| Alex Deymo | 4ea2d92 | 2017-02-05 07:35:32 +0000 | [diff] [blame] | 1328 |  | 
 | 1329 | TYPED_TEST(HttpFetcherTest, MultiHttpFetcherTerminateBetweenRangesTest) { | 
 | 1330 |   if (!this->test_.IsMulti()) | 
 | 1331 |     return; | 
 | 1332 |   const size_t kRangeTrigger = 1000; | 
 | 1333 |   MultiHttpFetcherTerminateTestDelegate delegate(kRangeTrigger); | 
 | 1334 |  | 
 | 1335 |   unique_ptr<HttpServer> server(this->test_.CreateServer()); | 
 | 1336 |   ASSERT_TRUE(server->started_); | 
 | 1337 |  | 
 | 1338 |   MultiRangeHttpFetcher* multi_fetcher = | 
 | 1339 |       static_cast<MultiRangeHttpFetcher*>(this->test_.NewLargeFetcher()); | 
 | 1340 |   ASSERT_TRUE(multi_fetcher); | 
 | 1341 |   // Transfer ownership of the fetcher to the delegate. | 
 | 1342 |   delegate.fetcher_.reset(multi_fetcher); | 
 | 1343 |   multi_fetcher->set_delegate(&delegate); | 
 | 1344 |  | 
 | 1345 |   multi_fetcher->ClearRanges(); | 
 | 1346 |   multi_fetcher->AddRange(45, kRangeTrigger); | 
 | 1347 |   multi_fetcher->AddRange(2000, 100); | 
 | 1348 |  | 
 | 1349 |   this->test_.fake_hardware()->SetIsOfficialBuild(false); | 
 | 1350 |  | 
 | 1351 |   StartTransfer(multi_fetcher, this->test_.BigUrl(server->GetPort())); | 
 | 1352 |   MessageLoop::current()->Run(); | 
 | 1353 |  | 
 | 1354 |   // Check that the delegate made it to the trigger point. | 
 | 1355 |   EXPECT_EQ(kRangeTrigger, delegate.bytes_downloaded_); | 
 | 1356 | } | 
| Gilad Arnold | 9bedeb5 | 2011-11-17 16:19:57 -0800 | [diff] [blame] | 1357 |  | 
| Darin Petkov | fc7a0ce | 2010-10-25 10:38:37 -0700 | [diff] [blame] | 1358 | class BlockedTransferTestDelegate : public HttpFetcherDelegate { | 
| Andrew de los Reyes | d57d147 | 2010-10-21 13:34:08 -0700 | [diff] [blame] | 1359 |  public: | 
| Amin Hassani | 0cd9d77 | 2018-07-31 23:55:43 -0700 | [diff] [blame] | 1360 |   bool ReceivedBytes(HttpFetcher* fetcher, | 
 | 1361 |                      const void* bytes, | 
 | 1362 |                      size_t length) override { | 
| Andrew de los Reyes | d57d147 | 2010-10-21 13:34:08 -0700 | [diff] [blame] | 1363 |     ADD_FAILURE(); | 
| Amin Hassani | 0cd9d77 | 2018-07-31 23:55:43 -0700 | [diff] [blame] | 1364 |     return true; | 
| Andrew de los Reyes | d57d147 | 2010-10-21 13:34:08 -0700 | [diff] [blame] | 1365 |   } | 
| Alex Deymo | 610277e | 2014-11-11 21:18:11 -0800 | [diff] [blame] | 1366 |   void TransferComplete(HttpFetcher* fetcher, bool successful) override { | 
| Andrew de los Reyes | d57d147 | 2010-10-21 13:34:08 -0700 | [diff] [blame] | 1367 |     EXPECT_FALSE(successful); | 
| Alex Deymo | 60ca1a7 | 2015-06-18 18:19:15 -0700 | [diff] [blame] | 1368 |     MessageLoop::current()->BreakLoop(); | 
| Andrew de los Reyes | d57d147 | 2010-10-21 13:34:08 -0700 | [diff] [blame] | 1369 |   } | 
| Amin Hassani | b268959 | 2019-01-13 17:04:28 -0800 | [diff] [blame] | 1370 |   void TransferTerminated(HttpFetcher* fetcher) override { ADD_FAILURE(); } | 
| Andrew de los Reyes | d57d147 | 2010-10-21 13:34:08 -0700 | [diff] [blame] | 1371 | }; | 
 | 1372 |  | 
| Kelvin Zhang | f0c73d4 | 2021-09-07 10:34:26 -0700 | [diff] [blame] | 1373 | void BlockedTransferTestHelper(AnyHttpFetcherFactory* fetcher_test, | 
| Alex Deymo | 60ca1a7 | 2015-06-18 18:19:15 -0700 | [diff] [blame] | 1374 |                                bool is_official_build) { | 
 | 1375 |   if (fetcher_test->IsMock() || fetcher_test->IsMulti()) | 
 | 1376 |     return; | 
 | 1377 |  | 
 | 1378 |   unique_ptr<HttpServer> server(fetcher_test->CreateServer()); | 
 | 1379 |   ASSERT_TRUE(server->started_); | 
 | 1380 |  | 
 | 1381 |   BlockedTransferTestDelegate delegate; | 
 | 1382 |   unique_ptr<HttpFetcher> fetcher(fetcher_test->NewLargeFetcher()); | 
 | 1383 |   LOG(INFO) << "is_official_build: " << is_official_build; | 
 | 1384 |   // NewLargeFetcher creates the HttpFetcher* with a FakeSystemState. | 
| Alex Deymo | c1c17b4 | 2015-11-23 03:53:15 -0300 | [diff] [blame] | 1385 |   fetcher_test->fake_hardware()->SetIsOfficialBuild(is_official_build); | 
| Alex Deymo | 60ca1a7 | 2015-06-18 18:19:15 -0700 | [diff] [blame] | 1386 |   fetcher->set_delegate(&delegate); | 
 | 1387 |  | 
| Amin Hassani | b268959 | 2019-01-13 17:04:28 -0800 | [diff] [blame] | 1388 |   MessageLoop::current()->PostTask( | 
 | 1389 |       FROM_HERE, | 
 | 1390 |       base::Bind( | 
 | 1391 |           StartTransfer, | 
 | 1392 |           fetcher.get(), | 
 | 1393 |           LocalServerUrlForPath(server->GetPort(), | 
 | 1394 |                                 fetcher_test->SmallUrl(server->GetPort())))); | 
| Alex Deymo | 60ca1a7 | 2015-06-18 18:19:15 -0700 | [diff] [blame] | 1395 |   MessageLoop::current()->Run(); | 
 | 1396 | } | 
| Andrew de los Reyes | d57d147 | 2010-10-21 13:34:08 -0700 | [diff] [blame] | 1397 |  | 
| Darin Petkov | fc7a0ce | 2010-10-25 10:38:37 -0700 | [diff] [blame] | 1398 | TYPED_TEST(HttpFetcherTest, BlockedTransferTest) { | 
| Alex Deymo | 60ca1a7 | 2015-06-18 18:19:15 -0700 | [diff] [blame] | 1399 |   BlockedTransferTestHelper(&this->test_, false); | 
 | 1400 | } | 
| Andrew de los Reyes | d57d147 | 2010-10-21 13:34:08 -0700 | [diff] [blame] | 1401 |  | 
| Alex Deymo | 60ca1a7 | 2015-06-18 18:19:15 -0700 | [diff] [blame] | 1402 | TYPED_TEST(HttpFetcherTest, BlockedTransferOfficialBuildTest) { | 
 | 1403 |   BlockedTransferTestHelper(&this->test_, true); | 
| Andrew de los Reyes | d57d147 | 2010-10-21 13:34:08 -0700 | [diff] [blame] | 1404 | } | 
 | 1405 |  | 
| Kelvin Zhang | f0c73d4 | 2021-09-07 10:34:26 -0700 | [diff] [blame] | 1406 | }  // namespace | 
 | 1407 |  | 
| rspangler@google.com | 49fdf18 | 2009-10-10 00:57:34 +0000 | [diff] [blame] | 1408 | }  // namespace chromeos_update_engine |