| Mike Frysinger | 8155d08 | 2012-04-06 15:23:18 -0400 | [diff] [blame] | 1 | // Copyright (c) 2012 The Chromium OS Authors. All rights reserved. | 
| rspangler@google.com | 49fdf18 | 2009-10-10 00:57:34 +0000 | [diff] [blame] | 2 | // Use of this source code is governed by a BSD-style license that can be | 
 | 3 | // found in the LICENSE file. | 
 | 4 |  | 
| Gilad Arnold | b6c562a | 2013-07-01 02:19:26 -0700 | [diff] [blame] | 5 | #include <netinet/in.h> | 
 | 6 | #include <netinet/ip.h> | 
 | 7 | #include <sys/socket.h> | 
| rspangler@google.com | 49fdf18 | 2009-10-10 00:57:34 +0000 | [diff] [blame] | 8 | #include <unistd.h> | 
| Darin Petkov | 41c2fcf | 2010-08-25 13:14:48 -0700 | [diff] [blame] | 9 |  | 
| adlr@google.com | c98a7ed | 2009-12-04 18:54:03 +0000 | [diff] [blame] | 10 | #include <string> | 
| Andrew de los Reyes | 3fd5d30 | 2010-10-07 20:07:18 -0700 | [diff] [blame] | 11 | #include <utility> | 
| adlr@google.com | c98a7ed | 2009-12-04 18:54:03 +0000 | [diff] [blame] | 12 | #include <vector> | 
| Darin Petkov | 41c2fcf | 2010-08-25 13:14:48 -0700 | [diff] [blame] | 13 |  | 
| Andrew de los Reyes | 4516810 | 2010-11-22 11:13:50 -0800 | [diff] [blame] | 14 | #include <base/logging.h> | 
| Chris Masone | d903c3b | 2011-05-12 15:35:46 -0700 | [diff] [blame] | 15 | #include <base/memory/scoped_ptr.h> | 
| Andrew de los Reyes | 4516810 | 2010-11-22 11:13:50 -0800 | [diff] [blame] | 16 | #include <base/string_util.h> | 
| Mike Frysinger | 8155d08 | 2012-04-06 15:23:18 -0400 | [diff] [blame] | 17 | #include <base/stringprintf.h> | 
| Gilad Arnold | 8e3f126 | 2013-01-08 14:59:54 -0800 | [diff] [blame] | 18 | #include <base/time.h> | 
| Jay Srinivasan | 4348879 | 2012-06-19 00:25:31 -0700 | [diff] [blame] | 19 | #include <chromeos/dbus/service_constants.h> | 
| Andrew de los Reyes | 4516810 | 2010-11-22 11:13:50 -0800 | [diff] [blame] | 20 | #include <glib.h> | 
 | 21 | #include <gtest/gtest.h> | 
 | 22 |  | 
| Gilad Arnold | 9bedeb5 | 2011-11-17 16:19:57 -0800 | [diff] [blame] | 23 | #include "update_engine/http_common.h" | 
| rspangler@google.com | 49fdf18 | 2009-10-10 00:57:34 +0000 | [diff] [blame] | 24 | #include "update_engine/libcurl_http_fetcher.h" | 
| Jay Srinivasan | 4348879 | 2012-06-19 00:25:31 -0700 | [diff] [blame] | 25 | #include "update_engine/mock_connection_manager.h" | 
| rspangler@google.com | 49fdf18 | 2009-10-10 00:57:34 +0000 | [diff] [blame] | 26 | #include "update_engine/mock_http_fetcher.h" | 
| Jay Srinivasan | 08fce04 | 2012-06-07 16:31:01 -0700 | [diff] [blame] | 27 | #include "update_engine/mock_system_state.h" | 
| Andrew de los Reyes | 819fef2 | 2010-12-17 11:33:58 -0800 | [diff] [blame] | 28 | #include "update_engine/multi_range_http_fetcher.h" | 
| Andrew de los Reyes | 4516810 | 2010-11-22 11:13:50 -0800 | [diff] [blame] | 29 | #include "update_engine/proxy_resolver.h" | 
| Jay Srinivasan | 08fce04 | 2012-06-07 16:31:01 -0700 | [diff] [blame] | 30 | #include "update_engine/utils.h" | 
| rspangler@google.com | 49fdf18 | 2009-10-10 00:57:34 +0000 | [diff] [blame] | 31 |  | 
| Andrew de los Reyes | 3fd5d30 | 2010-10-07 20:07:18 -0700 | [diff] [blame] | 32 | using std::make_pair; | 
| Andrew de los Reyes | 819fef2 | 2010-12-17 11:33:58 -0800 | [diff] [blame] | 33 | using std::pair; | 
| adlr@google.com | c98a7ed | 2009-12-04 18:54:03 +0000 | [diff] [blame] | 34 | using std::string; | 
 | 35 | using std::vector; | 
 | 36 |  | 
| Gilad Arnold | 8e3f126 | 2013-01-08 14:59:54 -0800 | [diff] [blame] | 37 | using base::TimeDelta; | 
| Jay Srinivasan | 4348879 | 2012-06-19 00:25:31 -0700 | [diff] [blame] | 38 | using testing::_; | 
 | 39 | using testing::SetArgumentPointee; | 
 | 40 | using testing::DoAll; | 
 | 41 | using testing::Return; | 
 | 42 |  | 
| Gilad Arnold | 9bedeb5 | 2011-11-17 16:19:57 -0800 | [diff] [blame] | 43 | namespace { | 
 | 44 |  | 
 | 45 | const int kBigLength           = 100000; | 
 | 46 | const int kMediumLength        = 1000; | 
| Gilad Arnold | 34bf1ee | 2012-02-09 16:16:02 -0800 | [diff] [blame] | 47 | const int kFlakyTruncateLength = 29000; | 
 | 48 | const int kFlakySleepEvery     = 3; | 
| Gilad Arnold | 9bedeb5 | 2011-11-17 16:19:57 -0800 | [diff] [blame] | 49 | const int kFlakySleepSecs      = 10; | 
 | 50 |  | 
 | 51 | }  // namespace | 
 | 52 |  | 
| rspangler@google.com | 49fdf18 | 2009-10-10 00:57:34 +0000 | [diff] [blame] | 53 | namespace chromeos_update_engine { | 
 | 54 |  | 
| Gilad Arnold | 9bedeb5 | 2011-11-17 16:19:57 -0800 | [diff] [blame] | 55 | static const char *kUnusedUrl = "unused://unused"; | 
 | 56 |  | 
| Gilad Arnold | b6c562a | 2013-07-01 02:19:26 -0700 | [diff] [blame] | 57 | static inline string LocalServerUrlForPath(in_port_t port, | 
 | 58 |                                            const string& path) { | 
 | 59 |   string port_str = (port ? StringPrintf(":%hu", port) : ""); | 
 | 60 |   return base::StringPrintf("http://127.0.0.1%s%s", port_str.c_str(), | 
 | 61 |                             path.c_str()); | 
| rspangler@google.com | 49fdf18 | 2009-10-10 00:57:34 +0000 | [diff] [blame] | 62 | } | 
 | 63 |  | 
| Gilad Arnold | 9bedeb5 | 2011-11-17 16:19:57 -0800 | [diff] [blame] | 64 | // | 
 | 65 | // Class hierarchy for HTTP server implementations. | 
 | 66 | // | 
 | 67 |  | 
 | 68 | class HttpServer { | 
| rspangler@google.com | 49fdf18 | 2009-10-10 00:57:34 +0000 | [diff] [blame] | 69 |  public: | 
| Gilad Arnold | 9bedeb5 | 2011-11-17 16:19:57 -0800 | [diff] [blame] | 70 |   // This makes it an abstract class (dirty but works). | 
 | 71 |   virtual ~HttpServer() = 0; | 
 | 72 |  | 
| Gilad Arnold | b6c562a | 2013-07-01 02:19:26 -0700 | [diff] [blame] | 73 |   virtual in_port_t GetPort() const { | 
 | 74 |     return 0; | 
 | 75 |   } | 
 | 76 |  | 
| rspangler@google.com | 49fdf18 | 2009-10-10 00:57:34 +0000 | [diff] [blame] | 77 |   bool started_; | 
 | 78 | }; | 
 | 79 |  | 
| Gilad Arnold | 9bedeb5 | 2011-11-17 16:19:57 -0800 | [diff] [blame] | 80 | HttpServer::~HttpServer() {} | 
| rspangler@google.com | 49fdf18 | 2009-10-10 00:57:34 +0000 | [diff] [blame] | 81 |  | 
| Gilad Arnold | 9bedeb5 | 2011-11-17 16:19:57 -0800 | [diff] [blame] | 82 |  | 
 | 83 | class NullHttpServer : public HttpServer { | 
| rspangler@google.com | 49fdf18 | 2009-10-10 00:57:34 +0000 | [diff] [blame] | 84 |  public: | 
| Gilad Arnold | 9bedeb5 | 2011-11-17 16:19:57 -0800 | [diff] [blame] | 85 |   NullHttpServer() { | 
 | 86 |     started_ = true; | 
| rspangler@google.com | 49fdf18 | 2009-10-10 00:57:34 +0000 | [diff] [blame] | 87 |   } | 
| rspangler@google.com | 49fdf18 | 2009-10-10 00:57:34 +0000 | [diff] [blame] | 88 | }; | 
 | 89 |  | 
| Gilad Arnold | 9bedeb5 | 2011-11-17 16:19:57 -0800 | [diff] [blame] | 90 |  | 
 | 91 | class PythonHttpServer : public HttpServer { | 
| rspangler@google.com | 49fdf18 | 2009-10-10 00:57:34 +0000 | [diff] [blame] | 92 |  public: | 
| Gilad Arnold | b6c562a | 2013-07-01 02:19:26 -0700 | [diff] [blame] | 93 |   PythonHttpServer() : pid_(-1), port_(0) { | 
| rspangler@google.com | 49fdf18 | 2009-10-10 00:57:34 +0000 | [diff] [blame] | 94 |     started_ = false; | 
| Gilad Arnold | b6c562a | 2013-07-01 02:19:26 -0700 | [diff] [blame] | 95 |  | 
 | 96 |     // Spawn the server process. | 
 | 97 |     gchar *argv[] = { | 
 | 98 |       const_cast<gchar*>("./test_http_server"), | 
 | 99 |       NULL }; | 
 | 100 |     GError *err; | 
 | 101 |     gint server_stdout = -1; | 
 | 102 |     if (!g_spawn_async_with_pipes(NULL, argv, NULL, G_SPAWN_DO_NOT_REAP_CHILD, | 
 | 103 |                                   NULL, NULL, &pid_, NULL, &server_stdout, NULL, | 
 | 104 |                                   &err)) { | 
 | 105 |       LOG(ERROR) << "failed to spawn http server process"; | 
| rspangler@google.com | 49fdf18 | 2009-10-10 00:57:34 +0000 | [diff] [blame] | 106 |       return; | 
 | 107 |     } | 
| Gilad Arnold | b6c562a | 2013-07-01 02:19:26 -0700 | [diff] [blame] | 108 |     CHECK_GT(pid_, 0); | 
 | 109 |     CHECK_GE(server_stdout, 0); | 
| Jay Srinivasan | 135a58b | 2012-07-13 12:46:49 -0700 | [diff] [blame] | 110 |     LOG(INFO) << "started http server with pid " << pid_; | 
| Gilad Arnold | b6c562a | 2013-07-01 02:19:26 -0700 | [diff] [blame] | 111 |  | 
 | 112 |     // Wait for server to begin accepting connections, obtain its port. | 
 | 113 |     char line[80]; | 
 | 114 |     const size_t listening_msg_prefix_len = strlen(kServerListeningMsgPrefix); | 
 | 115 |     CHECK_GT(sizeof(line), listening_msg_prefix_len); | 
 | 116 |     int line_len = read(server_stdout, line, sizeof(line) - 1); | 
 | 117 |     if (line_len <= static_cast<int>(listening_msg_prefix_len)) { | 
 | 118 |       if (line_len < 0) { | 
 | 119 |         LOG(ERROR) << "error reading http server stdout: " | 
 | 120 |                    << strerror(errno); | 
 | 121 |       } else { | 
 | 122 |         LOG(ERROR) << "server output too short"; | 
 | 123 |       } | 
 | 124 |       Terminate(true); | 
 | 125 |       return; | 
 | 126 |     } | 
 | 127 |  | 
 | 128 |     line[line_len] = '\0'; | 
 | 129 |     CHECK_EQ(strstr(line, kServerListeningMsgPrefix), line); | 
 | 130 |     const char* listening_port_str = line + listening_msg_prefix_len; | 
 | 131 |     char* end_ptr; | 
 | 132 |     long raw_port = strtol(listening_port_str, &end_ptr, 10); | 
 | 133 |     CHECK(!*end_ptr || *end_ptr == '\n'); | 
 | 134 |     port_ = static_cast<in_port_t>(raw_port); | 
 | 135 |     CHECK_GT(port_, 0); | 
| Andrew de los Reyes | 3270f74 | 2010-07-15 22:28:14 -0700 | [diff] [blame] | 136 |     started_ = true; | 
| Gilad Arnold | b6c562a | 2013-07-01 02:19:26 -0700 | [diff] [blame] | 137 |     LOG(INFO) << "server running, listening on port " << port_; | 
| Andrew de los Reyes | 3fd5d30 | 2010-10-07 20:07:18 -0700 | [diff] [blame] | 138 |     LOG(INFO) << "gdb attach now!"; | 
| rspangler@google.com | 49fdf18 | 2009-10-10 00:57:34 +0000 | [diff] [blame] | 139 |   } | 
| Gilad Arnold | 9bedeb5 | 2011-11-17 16:19:57 -0800 | [diff] [blame] | 140 |  | 
| rspangler@google.com | 49fdf18 | 2009-10-10 00:57:34 +0000 | [diff] [blame] | 141 |   ~PythonHttpServer() { | 
| Gilad Arnold | b6c562a | 2013-07-01 02:19:26 -0700 | [diff] [blame] | 142 |     // If there's no process, do nothing. | 
 | 143 |     if (pid_ == -1) | 
| rspangler@google.com | 49fdf18 | 2009-10-10 00:57:34 +0000 | [diff] [blame] | 144 |       return; | 
| Gilad Arnold | b6c562a | 2013-07-01 02:19:26 -0700 | [diff] [blame] | 145 |  | 
 | 146 |     // If server is responsive, request that it gracefully terminate. | 
 | 147 |     bool do_kill = false; | 
 | 148 |     if (started_) { | 
 | 149 |       LOG(INFO) << "running wget to exit"; | 
 | 150 |       if (system((string("wget -t 1 --output-document=/dev/null ") + | 
 | 151 |                   LocalServerUrlForPath(port_, "/quitquitquit")).c_str())) { | 
 | 152 |         LOG(WARNING) << "wget failed, resorting to brute force"; | 
 | 153 |         do_kill = true; | 
 | 154 |       } | 
| Jay Srinivasan | 135a58b | 2012-07-13 12:46:49 -0700 | [diff] [blame] | 155 |     } | 
 | 156 |  | 
| Gilad Arnold | b6c562a | 2013-07-01 02:19:26 -0700 | [diff] [blame] | 157 |     // Server not responding or wget failed, kill the process. | 
 | 158 |     Terminate(do_kill); | 
| rspangler@google.com | 49fdf18 | 2009-10-10 00:57:34 +0000 | [diff] [blame] | 159 |   } | 
| Gilad Arnold | 9bedeb5 | 2011-11-17 16:19:57 -0800 | [diff] [blame] | 160 |  | 
| Gilad Arnold | b6c562a | 2013-07-01 02:19:26 -0700 | [diff] [blame] | 161 |   virtual in_port_t GetPort() const { | 
 | 162 |     return port_; | 
 | 163 |   } | 
 | 164 |  | 
 | 165 |  private: | 
 | 166 |   void Terminate(bool do_kill) { | 
 | 167 |     ASSERT_GT(pid_, 0); | 
 | 168 |  | 
 | 169 |     if (do_kill) { | 
 | 170 |       LOG(INFO) << "terminating (SIGKILL) server process with pid " << pid_; | 
 | 171 |       kill(pid_, SIGKILL); | 
 | 172 |     } | 
 | 173 |  | 
 | 174 |     LOG(INFO) << "waiting for http server with pid " << pid_ << " to terminate"; | 
 | 175 |     int status; | 
 | 176 |     pid_t killed_pid = waitpid(pid_, &status, 0); | 
 | 177 |     ASSERT_EQ(killed_pid, pid_); | 
 | 178 |     LOG(INFO) << "http server with pid " << pid_ | 
 | 179 |               << " terminated with status " << status; | 
 | 180 |     pid_ = -1; | 
 | 181 |   } | 
 | 182 |  | 
 | 183 |   static const char* kServerListeningMsgPrefix; | 
 | 184 |  | 
| rspangler@google.com | 49fdf18 | 2009-10-10 00:57:34 +0000 | [diff] [blame] | 185 |   GPid pid_; | 
| Gilad Arnold | b6c562a | 2013-07-01 02:19:26 -0700 | [diff] [blame] | 186 |   in_port_t port_; | 
| rspangler@google.com | 49fdf18 | 2009-10-10 00:57:34 +0000 | [diff] [blame] | 187 | }; | 
 | 188 |  | 
| Gilad Arnold | b6c562a | 2013-07-01 02:19:26 -0700 | [diff] [blame] | 189 | const char* PythonHttpServer::kServerListeningMsgPrefix = "listening on port "; | 
 | 190 |  | 
| Gilad Arnold | 9bedeb5 | 2011-11-17 16:19:57 -0800 | [diff] [blame] | 191 | // | 
 | 192 | // Class hierarchy for HTTP fetcher test wrappers. | 
 | 193 | // | 
 | 194 |  | 
 | 195 | class AnyHttpFetcherTest { | 
| rspangler@google.com | 49fdf18 | 2009-10-10 00:57:34 +0000 | [diff] [blame] | 196 |  public: | 
| Jay Srinivasan | 4348879 | 2012-06-19 00:25:31 -0700 | [diff] [blame] | 197 |   AnyHttpFetcherTest() | 
 | 198 |       : mock_connection_manager_(&mock_system_state_) { | 
| Jay Srinivasan | 6f6ea00 | 2012-12-14 11:26:28 -0800 | [diff] [blame] | 199 |     mock_system_state_.set_connection_manager(&mock_connection_manager_); | 
| Jay Srinivasan | 4348879 | 2012-06-19 00:25:31 -0700 | [diff] [blame] | 200 |   } | 
 | 201 |  | 
 | 202 |  virtual HttpFetcher* NewLargeFetcher(size_t num_proxies) = 0; | 
| Gilad Arnold | 9bedeb5 | 2011-11-17 16:19:57 -0800 | [diff] [blame] | 203 |   HttpFetcher* NewLargeFetcher() { | 
 | 204 |     return NewLargeFetcher(1); | 
 | 205 |   } | 
 | 206 |  | 
 | 207 |   virtual HttpFetcher* NewSmallFetcher(size_t num_proxies) = 0; | 
 | 208 |   HttpFetcher* NewSmallFetcher() { | 
 | 209 |     return NewSmallFetcher(1); | 
 | 210 |   } | 
 | 211 |  | 
| Gilad Arnold | b6c562a | 2013-07-01 02:19:26 -0700 | [diff] [blame] | 212 |   virtual string BigUrl(in_port_t port) const { return kUnusedUrl; } | 
 | 213 |   virtual string SmallUrl(in_port_t port) const { return kUnusedUrl; } | 
 | 214 |   virtual string ErrorUrl(in_port_t port) const { return kUnusedUrl; } | 
| Gilad Arnold | 9bedeb5 | 2011-11-17 16:19:57 -0800 | [diff] [blame] | 215 |  | 
 | 216 |   virtual bool IsMock() const = 0; | 
 | 217 |   virtual bool IsMulti() const = 0; | 
 | 218 |  | 
 | 219 |   virtual void IgnoreServerAborting(HttpServer* server) const {} | 
 | 220 |  | 
 | 221 |   virtual HttpServer *CreateServer() = 0; | 
 | 222 |  | 
 | 223 |  protected: | 
 | 224 |   DirectProxyResolver proxy_resolver_; | 
| Jay Srinivasan | 4348879 | 2012-06-19 00:25:31 -0700 | [diff] [blame] | 225 |   MockSystemState mock_system_state_; | 
 | 226 |   MockConnectionManager mock_connection_manager_; | 
| Gilad Arnold | 9bedeb5 | 2011-11-17 16:19:57 -0800 | [diff] [blame] | 227 | }; | 
 | 228 |  | 
 | 229 | class MockHttpFetcherTest : public AnyHttpFetcherTest { | 
 | 230 |  public: | 
 | 231 |   // Necessary to unhide the definition in the base class. | 
 | 232 |   using AnyHttpFetcherTest::NewLargeFetcher; | 
 | 233 |   virtual HttpFetcher* NewLargeFetcher(size_t num_proxies) { | 
 | 234 |     vector<char> big_data(1000000); | 
 | 235 |     CHECK(num_proxies > 0); | 
 | 236 |     proxy_resolver_.set_num_proxies(num_proxies); | 
 | 237 |     return new MockHttpFetcher( | 
 | 238 |         big_data.data(), | 
 | 239 |         big_data.size(), | 
 | 240 |         reinterpret_cast<ProxyResolver*>(&proxy_resolver_)); | 
 | 241 |   } | 
 | 242 |  | 
 | 243 |   // Necessary to unhide the definition in the base class. | 
 | 244 |   using AnyHttpFetcherTest::NewSmallFetcher; | 
 | 245 |   virtual HttpFetcher* NewSmallFetcher(size_t num_proxies) { | 
 | 246 |     CHECK(num_proxies > 0); | 
 | 247 |     proxy_resolver_.set_num_proxies(num_proxies); | 
 | 248 |     return new MockHttpFetcher( | 
 | 249 |         "x", | 
 | 250 |         1, | 
 | 251 |         reinterpret_cast<ProxyResolver*>(&proxy_resolver_)); | 
 | 252 |   } | 
 | 253 |  | 
 | 254 |   virtual bool IsMock() const { return true; } | 
 | 255 |   virtual bool IsMulti() const { return false; } | 
 | 256 |  | 
 | 257 |   virtual HttpServer *CreateServer() { | 
 | 258 |     return new NullHttpServer; | 
 | 259 |   } | 
 | 260 | }; | 
 | 261 |  | 
 | 262 | class LibcurlHttpFetcherTest : public AnyHttpFetcherTest { | 
 | 263 |  public: | 
 | 264 |   // Necessary to unhide the definition in the base class. | 
 | 265 |   using AnyHttpFetcherTest::NewLargeFetcher; | 
 | 266 |   virtual HttpFetcher* NewLargeFetcher(size_t num_proxies) { | 
 | 267 |     CHECK(num_proxies > 0); | 
 | 268 |     proxy_resolver_.set_num_proxies(num_proxies); | 
| Andrew de los Reyes | 4516810 | 2010-11-22 11:13:50 -0800 | [diff] [blame] | 269 |     LibcurlHttpFetcher *ret = new | 
| Jay Srinivasan | 08fce04 | 2012-06-07 16:31:01 -0700 | [diff] [blame] | 270 |         LibcurlHttpFetcher(reinterpret_cast<ProxyResolver*>(&proxy_resolver_), | 
| Gilad Arnold | 7c04e76 | 2012-05-23 10:54:02 -0700 | [diff] [blame] | 271 |                            &mock_system_state_, false); | 
| Darin Petkov | b83371f | 2010-08-17 09:34:49 -0700 | [diff] [blame] | 272 |     // Speed up test execution. | 
 | 273 |     ret->set_idle_seconds(1); | 
 | 274 |     ret->set_retry_seconds(1); | 
| Darin Petkov | fc7a0ce | 2010-10-25 10:38:37 -0700 | [diff] [blame] | 275 |     ret->SetBuildType(false); | 
| rspangler@google.com | 49fdf18 | 2009-10-10 00:57:34 +0000 | [diff] [blame] | 276 |     return ret; | 
 | 277 |   } | 
| Gilad Arnold | 9bedeb5 | 2011-11-17 16:19:57 -0800 | [diff] [blame] | 278 |  | 
 | 279 |   // Necessary to unhide the definition in the base class. | 
 | 280 |   using AnyHttpFetcherTest::NewSmallFetcher; | 
 | 281 |   virtual HttpFetcher* NewSmallFetcher(size_t num_proxies) { | 
 | 282 |     return NewLargeFetcher(num_proxies); | 
| rspangler@google.com | 49fdf18 | 2009-10-10 00:57:34 +0000 | [diff] [blame] | 283 |   } | 
| Gilad Arnold | 9bedeb5 | 2011-11-17 16:19:57 -0800 | [diff] [blame] | 284 |  | 
| Gilad Arnold | b6c562a | 2013-07-01 02:19:26 -0700 | [diff] [blame] | 285 |   virtual string BigUrl(in_port_t port) const { | 
 | 286 |     return LocalServerUrlForPath(port, | 
 | 287 |                                  base::StringPrintf("/download/%d", | 
| Gilad Arnold | 9bedeb5 | 2011-11-17 16:19:57 -0800 | [diff] [blame] | 288 |                                                     kBigLength)); | 
| rspangler@google.com | 49fdf18 | 2009-10-10 00:57:34 +0000 | [diff] [blame] | 289 |   } | 
| Gilad Arnold | b6c562a | 2013-07-01 02:19:26 -0700 | [diff] [blame] | 290 |   virtual string SmallUrl(in_port_t port) const { | 
 | 291 |     return LocalServerUrlForPath(port, "/foo"); | 
| rspangler@google.com | 49fdf18 | 2009-10-10 00:57:34 +0000 | [diff] [blame] | 292 |   } | 
| Gilad Arnold | b6c562a | 2013-07-01 02:19:26 -0700 | [diff] [blame] | 293 |   virtual string ErrorUrl(in_port_t port) const { | 
 | 294 |     return LocalServerUrlForPath(port, "/error"); | 
| Gilad Arnold | 48085ba | 2011-11-16 09:36:08 -0800 | [diff] [blame] | 295 |   } | 
| Gilad Arnold | 9bedeb5 | 2011-11-17 16:19:57 -0800 | [diff] [blame] | 296 |  | 
 | 297 |   virtual bool IsMock() const { return false; } | 
 | 298 |   virtual bool IsMulti() const { return false; } | 
 | 299 |  | 
 | 300 |   virtual void IgnoreServerAborting(HttpServer* server) const { | 
| Gilad Arnold | b6c562a | 2013-07-01 02:19:26 -0700 | [diff] [blame] | 301 |     // Nothing to do. | 
| Andrew de los Reyes | 08c4e27 | 2010-04-15 14:02:17 -0700 | [diff] [blame] | 302 |   } | 
| Gilad Arnold | 9bedeb5 | 2011-11-17 16:19:57 -0800 | [diff] [blame] | 303 |  | 
 | 304 |   virtual HttpServer *CreateServer() { | 
 | 305 |     return new PythonHttpServer; | 
 | 306 |   } | 
| rspangler@google.com | 49fdf18 | 2009-10-10 00:57:34 +0000 | [diff] [blame] | 307 | }; | 
 | 308 |  | 
| Gilad Arnold | 9bedeb5 | 2011-11-17 16:19:57 -0800 | [diff] [blame] | 309 | class MultiRangeHttpFetcherTest : public LibcurlHttpFetcherTest { | 
| Andrew de los Reyes | 3fd5d30 | 2010-10-07 20:07:18 -0700 | [diff] [blame] | 310 |  public: | 
| Gilad Arnold | 9bedeb5 | 2011-11-17 16:19:57 -0800 | [diff] [blame] | 311 |   // Necessary to unhide the definition in the base class. | 
 | 312 |   using AnyHttpFetcherTest::NewLargeFetcher; | 
 | 313 |   virtual HttpFetcher* NewLargeFetcher(size_t num_proxies) { | 
 | 314 |     CHECK(num_proxies > 0); | 
 | 315 |     proxy_resolver_.set_num_proxies(num_proxies); | 
| Andrew de los Reyes | 819fef2 | 2010-12-17 11:33:58 -0800 | [diff] [blame] | 316 |     ProxyResolver* resolver = | 
 | 317 |         reinterpret_cast<ProxyResolver*>(&proxy_resolver_); | 
| Gilad Arnold | 7c04e76 | 2012-05-23 10:54:02 -0700 | [diff] [blame] | 318 |     MultiRangeHttpFetcher *ret = | 
 | 319 |         new MultiRangeHttpFetcher( | 
 | 320 |             new LibcurlHttpFetcher(resolver, &mock_system_state_, false)); | 
| Andrew de los Reyes | 819fef2 | 2010-12-17 11:33:58 -0800 | [diff] [blame] | 321 |     ret->ClearRanges(); | 
| Gilad Arnold | e4ad250 | 2011-12-29 17:08:54 -0800 | [diff] [blame] | 322 |     ret->AddRange(0); | 
| Andrew de los Reyes | 3fd5d30 | 2010-10-07 20:07:18 -0700 | [diff] [blame] | 323 |     // Speed up test execution. | 
 | 324 |     ret->set_idle_seconds(1); | 
 | 325 |     ret->set_retry_seconds(1); | 
| Darin Petkov | fc7a0ce | 2010-10-25 10:38:37 -0700 | [diff] [blame] | 326 |     ret->SetBuildType(false); | 
| Andrew de los Reyes | 3fd5d30 | 2010-10-07 20:07:18 -0700 | [diff] [blame] | 327 |     return ret; | 
 | 328 |   } | 
| Gilad Arnold | 9bedeb5 | 2011-11-17 16:19:57 -0800 | [diff] [blame] | 329 |  | 
 | 330 |   // Necessary to unhide the definition in the base class. | 
 | 331 |   using AnyHttpFetcherTest::NewSmallFetcher; | 
 | 332 |   virtual HttpFetcher* NewSmallFetcher(size_t num_proxies) { | 
 | 333 |     return NewLargeFetcher(num_proxies); | 
 | 334 |   } | 
 | 335 |  | 
 | 336 |   virtual bool IsMulti() const { return true; } | 
| Andrew de los Reyes | 3fd5d30 | 2010-10-07 20:07:18 -0700 | [diff] [blame] | 337 | }; | 
 | 338 |  | 
| Gilad Arnold | 9bedeb5 | 2011-11-17 16:19:57 -0800 | [diff] [blame] | 339 |  | 
 | 340 | // | 
 | 341 | // Infrastructure for type tests of HTTP fetcher. | 
 | 342 | // See: http://code.google.com/p/googletest/wiki/AdvancedGuide#Typed_Tests | 
 | 343 | // | 
 | 344 |  | 
 | 345 | // Fixture class template. We use an explicit constraint to guarantee that it | 
 | 346 | // can only be instantiated with an AnyHttpFetcherTest type, see: | 
 | 347 | // http://www2.research.att.com/~bs/bs_faq2.html#constraints | 
 | 348 | template <typename T> | 
 | 349 | class HttpFetcherTest : public ::testing::Test { | 
 | 350 |  public: | 
 | 351 |   T test_; | 
 | 352 |  | 
 | 353 |  private: | 
 | 354 |   static void TypeConstraint(T *a) { | 
 | 355 |     AnyHttpFetcherTest *b = a; | 
| Yunlian Jiang | 2dac576 | 2013-04-12 09:53:09 -0700 | [diff] [blame] | 356 |     if (b == 0) // Silence compiler warning of unused variable. | 
 | 357 |       *b = a; | 
| Gilad Arnold | 9bedeb5 | 2011-11-17 16:19:57 -0800 | [diff] [blame] | 358 |   } | 
 | 359 | }; | 
 | 360 |  | 
 | 361 | // Test case types list. | 
 | 362 | typedef ::testing::Types<LibcurlHttpFetcherTest, | 
 | 363 |                          MockHttpFetcherTest, | 
 | 364 |                          MultiRangeHttpFetcherTest> HttpFetcherTestTypes; | 
| rspangler@google.com | 49fdf18 | 2009-10-10 00:57:34 +0000 | [diff] [blame] | 365 | TYPED_TEST_CASE(HttpFetcherTest, HttpFetcherTestTypes); | 
 | 366 |  | 
| Gilad Arnold | 9bedeb5 | 2011-11-17 16:19:57 -0800 | [diff] [blame] | 367 |  | 
| rspangler@google.com | 49fdf18 | 2009-10-10 00:57:34 +0000 | [diff] [blame] | 368 | namespace { | 
 | 369 | class HttpFetcherTestDelegate : public HttpFetcherDelegate { | 
| adlr@google.com | c98a7ed | 2009-12-04 18:54:03 +0000 | [diff] [blame] | 370 |  public: | 
| Gilad Arnold | 9bedeb5 | 2011-11-17 16:19:57 -0800 | [diff] [blame] | 371 |   HttpFetcherTestDelegate() : | 
| Gilad Arnold | 48085ba | 2011-11-16 09:36:08 -0800 | [diff] [blame] | 372 |       is_expect_error_(false), times_transfer_complete_called_(0), | 
 | 373 |       times_transfer_terminated_called_(0), times_received_bytes_called_(0) {} | 
 | 374 |  | 
| rspangler@google.com | 49fdf18 | 2009-10-10 00:57:34 +0000 | [diff] [blame] | 375 |   virtual void ReceivedBytes(HttpFetcher* fetcher, | 
 | 376 |                              const char* bytes, int length) { | 
 | 377 |     char str[length + 1]; | 
 | 378 |     memset(str, 0, length + 1); | 
 | 379 |     memcpy(str, bytes, length); | 
| Gilad Arnold | 48085ba | 2011-11-16 09:36:08 -0800 | [diff] [blame] | 380 |  | 
 | 381 |     // Update counters | 
 | 382 |     times_received_bytes_called_++; | 
| rspangler@google.com | 49fdf18 | 2009-10-10 00:57:34 +0000 | [diff] [blame] | 383 |   } | 
| Gilad Arnold | 48085ba | 2011-11-16 09:36:08 -0800 | [diff] [blame] | 384 |  | 
| rspangler@google.com | 49fdf18 | 2009-10-10 00:57:34 +0000 | [diff] [blame] | 385 |   virtual void TransferComplete(HttpFetcher* fetcher, bool successful) { | 
| Gilad Arnold | 48085ba | 2011-11-16 09:36:08 -0800 | [diff] [blame] | 386 |     if (is_expect_error_) | 
| Gilad Arnold | 9bedeb5 | 2011-11-17 16:19:57 -0800 | [diff] [blame] | 387 |       EXPECT_EQ(kHttpResponseNotFound, fetcher->http_response_code()); | 
| Gilad Arnold | 48085ba | 2011-11-16 09:36:08 -0800 | [diff] [blame] | 388 |     else | 
| Gilad Arnold | 9bedeb5 | 2011-11-17 16:19:57 -0800 | [diff] [blame] | 389 |       EXPECT_EQ(kHttpResponseOk, fetcher->http_response_code()); | 
| rspangler@google.com | 49fdf18 | 2009-10-10 00:57:34 +0000 | [diff] [blame] | 390 |     g_main_loop_quit(loop_); | 
| Gilad Arnold | 48085ba | 2011-11-16 09:36:08 -0800 | [diff] [blame] | 391 |  | 
 | 392 |     // Update counter | 
 | 393 |     times_transfer_complete_called_++; | 
| rspangler@google.com | 49fdf18 | 2009-10-10 00:57:34 +0000 | [diff] [blame] | 394 |   } | 
| Gilad Arnold | 48085ba | 2011-11-16 09:36:08 -0800 | [diff] [blame] | 395 |  | 
| Darin Petkov | 9ce452b | 2010-11-17 14:33:28 -0800 | [diff] [blame] | 396 |   virtual void TransferTerminated(HttpFetcher* fetcher) { | 
 | 397 |     ADD_FAILURE(); | 
| Gilad Arnold | 48085ba | 2011-11-16 09:36:08 -0800 | [diff] [blame] | 398 |     times_transfer_terminated_called_++; | 
| Darin Petkov | 9ce452b | 2010-11-17 14:33:28 -0800 | [diff] [blame] | 399 |   } | 
| Gilad Arnold | 48085ba | 2011-11-16 09:36:08 -0800 | [diff] [blame] | 400 |  | 
| rspangler@google.com | 49fdf18 | 2009-10-10 00:57:34 +0000 | [diff] [blame] | 401 |   GMainLoop* loop_; | 
| Gilad Arnold | 48085ba | 2011-11-16 09:36:08 -0800 | [diff] [blame] | 402 |  | 
 | 403 |   // Are we expecting an error response? (default: no) | 
 | 404 |   bool is_expect_error_; | 
 | 405 |  | 
 | 406 |   // Counters for callback invocations. | 
 | 407 |   int times_transfer_complete_called_; | 
 | 408 |   int times_transfer_terminated_called_; | 
 | 409 |   int times_received_bytes_called_; | 
| rspangler@google.com | 49fdf18 | 2009-10-10 00:57:34 +0000 | [diff] [blame] | 410 | }; | 
| adlr@google.com | c98a7ed | 2009-12-04 18:54:03 +0000 | [diff] [blame] | 411 |  | 
 | 412 | struct StartTransferArgs { | 
 | 413 |   HttpFetcher *http_fetcher; | 
 | 414 |   string url; | 
 | 415 | }; | 
 | 416 |  | 
 | 417 | gboolean StartTransfer(gpointer data) { | 
 | 418 |   StartTransferArgs *args = reinterpret_cast<StartTransferArgs*>(data); | 
 | 419 |   args->http_fetcher->BeginTransfer(args->url); | 
 | 420 |   return FALSE; | 
 | 421 | } | 
| rspangler@google.com | 49fdf18 | 2009-10-10 00:57:34 +0000 | [diff] [blame] | 422 | }  // namespace {} | 
 | 423 |  | 
 | 424 | TYPED_TEST(HttpFetcherTest, SimpleTest) { | 
| Andrew de los Reyes | 9bbd187 | 2010-07-16 14:52:29 -0700 | [diff] [blame] | 425 |   GMainLoop* loop = g_main_loop_new(g_main_context_default(), FALSE); | 
| rspangler@google.com | 49fdf18 | 2009-10-10 00:57:34 +0000 | [diff] [blame] | 426 |   { | 
 | 427 |     HttpFetcherTestDelegate delegate; | 
 | 428 |     delegate.loop_ = loop; | 
| Gilad Arnold | 9bedeb5 | 2011-11-17 16:19:57 -0800 | [diff] [blame] | 429 |     scoped_ptr<HttpFetcher> fetcher(this->test_.NewSmallFetcher()); | 
| rspangler@google.com | 49fdf18 | 2009-10-10 00:57:34 +0000 | [diff] [blame] | 430 |     fetcher->set_delegate(&delegate); | 
 | 431 |  | 
| Jay Srinivasan | 4348879 | 2012-06-19 00:25:31 -0700 | [diff] [blame] | 432 |     MockConnectionManager* mock_cm = dynamic_cast<MockConnectionManager*>( | 
| Jay Srinivasan | 6f6ea00 | 2012-12-14 11:26:28 -0800 | [diff] [blame] | 433 |         fetcher->GetSystemState()->connection_manager()); | 
| Jay Srinivasan | 4348879 | 2012-06-19 00:25:31 -0700 | [diff] [blame] | 434 |     EXPECT_CALL(*mock_cm, GetConnectionType(_,_)) | 
 | 435 |       .WillRepeatedly(DoAll(SetArgumentPointee<1>(kNetWifi), Return(true))); | 
 | 436 |     EXPECT_CALL(*mock_cm, IsUpdateAllowedOver(kNetWifi)) | 
 | 437 |       .WillRepeatedly(Return(true)); | 
 | 438 |     EXPECT_CALL(*mock_cm, StringForConnectionType(kNetWifi)) | 
 | 439 |       .WillRepeatedly(Return(flimflam::kTypeWifi)); | 
 | 440 |  | 
| Gilad Arnold | 9bedeb5 | 2011-11-17 16:19:57 -0800 | [diff] [blame] | 441 |     scoped_ptr<HttpServer> server(this->test_.CreateServer()); | 
 | 442 |     ASSERT_TRUE(server->started_); | 
| rspangler@google.com | 49fdf18 | 2009-10-10 00:57:34 +0000 | [diff] [blame] | 443 |  | 
| Gilad Arnold | b6c562a | 2013-07-01 02:19:26 -0700 | [diff] [blame] | 444 |     StartTransferArgs start_xfer_args = { | 
 | 445 |       fetcher.get(), this->test_.SmallUrl(server->GetPort())}; | 
| adlr@google.com | c98a7ed | 2009-12-04 18:54:03 +0000 | [diff] [blame] | 446 |  | 
 | 447 |     g_timeout_add(0, StartTransfer, &start_xfer_args); | 
| rspangler@google.com | 49fdf18 | 2009-10-10 00:57:34 +0000 | [diff] [blame] | 448 |     g_main_loop_run(loop); | 
 | 449 |   } | 
 | 450 |   g_main_loop_unref(loop); | 
 | 451 | } | 
 | 452 |  | 
| Andrew de los Reyes | 3270f74 | 2010-07-15 22:28:14 -0700 | [diff] [blame] | 453 | TYPED_TEST(HttpFetcherTest, SimpleBigTest) { | 
| Andrew de los Reyes | 9bbd187 | 2010-07-16 14:52:29 -0700 | [diff] [blame] | 454 |   GMainLoop* loop = g_main_loop_new(g_main_context_default(), FALSE); | 
| Andrew de los Reyes | 3270f74 | 2010-07-15 22:28:14 -0700 | [diff] [blame] | 455 |   { | 
 | 456 |     HttpFetcherTestDelegate delegate; | 
 | 457 |     delegate.loop_ = loop; | 
| Gilad Arnold | 9bedeb5 | 2011-11-17 16:19:57 -0800 | [diff] [blame] | 458 |     scoped_ptr<HttpFetcher> fetcher(this->test_.NewLargeFetcher()); | 
| Andrew de los Reyes | 3270f74 | 2010-07-15 22:28:14 -0700 | [diff] [blame] | 459 |     fetcher->set_delegate(&delegate); | 
 | 460 |  | 
| Jay Srinivasan | 4348879 | 2012-06-19 00:25:31 -0700 | [diff] [blame] | 461 |     MockConnectionManager* mock_cm = dynamic_cast<MockConnectionManager*>( | 
| Jay Srinivasan | 6f6ea00 | 2012-12-14 11:26:28 -0800 | [diff] [blame] | 462 |         fetcher->GetSystemState()->connection_manager()); | 
| Jay Srinivasan | 4348879 | 2012-06-19 00:25:31 -0700 | [diff] [blame] | 463 |     EXPECT_CALL(*mock_cm, GetConnectionType(_,_)) | 
 | 464 |       .WillRepeatedly(DoAll(SetArgumentPointee<1>(kNetEthernet), Return(true))); | 
 | 465 |     EXPECT_CALL(*mock_cm, IsUpdateAllowedOver(kNetEthernet)) | 
 | 466 |       .WillRepeatedly(Return(true)); | 
 | 467 |     EXPECT_CALL(*mock_cm, StringForConnectionType(kNetEthernet)) | 
 | 468 |       .WillRepeatedly(Return(flimflam::kTypeEthernet)); | 
 | 469 |  | 
| Gilad Arnold | 9bedeb5 | 2011-11-17 16:19:57 -0800 | [diff] [blame] | 470 |     scoped_ptr<HttpServer> server(this->test_.CreateServer()); | 
 | 471 |     ASSERT_TRUE(server->started_); | 
| Andrew de los Reyes | 3270f74 | 2010-07-15 22:28:14 -0700 | [diff] [blame] | 472 |  | 
| Gilad Arnold | b6c562a | 2013-07-01 02:19:26 -0700 | [diff] [blame] | 473 |     StartTransferArgs start_xfer_args = { | 
 | 474 |       fetcher.get(), this->test_.BigUrl(server->GetPort())}; | 
| Andrew de los Reyes | 3270f74 | 2010-07-15 22:28:14 -0700 | [diff] [blame] | 475 |  | 
 | 476 |     g_timeout_add(0, StartTransfer, &start_xfer_args); | 
 | 477 |     g_main_loop_run(loop); | 
 | 478 |   } | 
 | 479 |   g_main_loop_unref(loop); | 
 | 480 | } | 
 | 481 |  | 
| Gilad Arnold | 48085ba | 2011-11-16 09:36:08 -0800 | [diff] [blame] | 482 | // Issue #9648: when server returns an error HTTP response, the fetcher needs to | 
 | 483 | // terminate transfer prematurely, rather than try to process the error payload. | 
 | 484 | TYPED_TEST(HttpFetcherTest, ErrorTest) { | 
| Gilad Arnold | 9bedeb5 | 2011-11-17 16:19:57 -0800 | [diff] [blame] | 485 |   if (this->test_.IsMock() || this->test_.IsMulti()) | 
| Gilad Arnold | 48085ba | 2011-11-16 09:36:08 -0800 | [diff] [blame] | 486 |     return; | 
 | 487 |   GMainLoop* loop = g_main_loop_new(g_main_context_default(), FALSE); | 
 | 488 |   { | 
 | 489 |     HttpFetcherTestDelegate delegate; | 
 | 490 |     delegate.loop_ = loop; | 
 | 491 |  | 
 | 492 |     // Delegate should expect an error response. | 
 | 493 |     delegate.is_expect_error_ = true; | 
 | 494 |  | 
| Gilad Arnold | 9bedeb5 | 2011-11-17 16:19:57 -0800 | [diff] [blame] | 495 |     scoped_ptr<HttpFetcher> fetcher(this->test_.NewSmallFetcher()); | 
| Gilad Arnold | 48085ba | 2011-11-16 09:36:08 -0800 | [diff] [blame] | 496 |     fetcher->set_delegate(&delegate); | 
 | 497 |  | 
| Jay Srinivasan | 4348879 | 2012-06-19 00:25:31 -0700 | [diff] [blame] | 498 |     MockConnectionManager* mock_cm = dynamic_cast<MockConnectionManager*>( | 
| Jay Srinivasan | 6f6ea00 | 2012-12-14 11:26:28 -0800 | [diff] [blame] | 499 |         fetcher->GetSystemState()->connection_manager()); | 
| Jay Srinivasan | 4348879 | 2012-06-19 00:25:31 -0700 | [diff] [blame] | 500 |     EXPECT_CALL(*mock_cm, GetConnectionType(_,_)) | 
 | 501 |       .WillRepeatedly(DoAll(SetArgumentPointee<1>(kNetWimax), Return(true))); | 
 | 502 |     EXPECT_CALL(*mock_cm, IsUpdateAllowedOver(kNetWimax)) | 
 | 503 |       .WillRepeatedly(Return(true)); | 
 | 504 |     EXPECT_CALL(*mock_cm, StringForConnectionType(kNetWimax)) | 
 | 505 |       .WillRepeatedly(Return(flimflam::kTypeWimax)); | 
 | 506 |  | 
| Gilad Arnold | 9bedeb5 | 2011-11-17 16:19:57 -0800 | [diff] [blame] | 507 |     scoped_ptr<HttpServer> server(this->test_.CreateServer()); | 
 | 508 |     ASSERT_TRUE(server->started_); | 
| Gilad Arnold | 48085ba | 2011-11-16 09:36:08 -0800 | [diff] [blame] | 509 |  | 
| Gilad Arnold | 9bedeb5 | 2011-11-17 16:19:57 -0800 | [diff] [blame] | 510 |     StartTransferArgs start_xfer_args = { | 
 | 511 |       fetcher.get(), | 
| Gilad Arnold | b6c562a | 2013-07-01 02:19:26 -0700 | [diff] [blame] | 512 |       this->test_.ErrorUrl(server->GetPort()) | 
| Gilad Arnold | 9bedeb5 | 2011-11-17 16:19:57 -0800 | [diff] [blame] | 513 |     }; | 
| Gilad Arnold | 48085ba | 2011-11-16 09:36:08 -0800 | [diff] [blame] | 514 |  | 
 | 515 |     g_timeout_add(0, StartTransfer, &start_xfer_args); | 
 | 516 |     g_main_loop_run(loop); | 
 | 517 |  | 
 | 518 |     // Make sure that no bytes were received. | 
 | 519 |     CHECK_EQ(delegate.times_received_bytes_called_, 0); | 
| Mike Frysinger | 0f9547d | 2012-02-16 12:11:37 -0500 | [diff] [blame] | 520 |     CHECK_EQ(fetcher->GetBytesDownloaded(), static_cast<size_t>(0)); | 
| Gilad Arnold | 48085ba | 2011-11-16 09:36:08 -0800 | [diff] [blame] | 521 |  | 
 | 522 |     // Make sure that transfer completion was signaled once, and no termination | 
 | 523 |     // was signaled. | 
 | 524 |     CHECK_EQ(delegate.times_transfer_complete_called_, 1); | 
 | 525 |     CHECK_EQ(delegate.times_transfer_terminated_called_, 0); | 
 | 526 |   } | 
 | 527 |   g_main_loop_unref(loop); | 
 | 528 | } | 
 | 529 |  | 
| rspangler@google.com | 49fdf18 | 2009-10-10 00:57:34 +0000 | [diff] [blame] | 530 | namespace { | 
 | 531 | class PausingHttpFetcherTestDelegate : public HttpFetcherDelegate { | 
 | 532 |  public: | 
 | 533 |   virtual void ReceivedBytes(HttpFetcher* fetcher, | 
 | 534 |                              const char* bytes, int length) { | 
 | 535 |     char str[length + 1]; | 
| rspangler@google.com | 49fdf18 | 2009-10-10 00:57:34 +0000 | [diff] [blame] | 536 |     memset(str, 0, length + 1); | 
 | 537 |     memcpy(str, bytes, length); | 
 | 538 |     CHECK(!paused_); | 
 | 539 |     paused_ = true; | 
 | 540 |     fetcher->Pause(); | 
| rspangler@google.com | 49fdf18 | 2009-10-10 00:57:34 +0000 | [diff] [blame] | 541 |   } | 
 | 542 |   virtual void TransferComplete(HttpFetcher* fetcher, bool successful) { | 
 | 543 |     g_main_loop_quit(loop_); | 
 | 544 |   } | 
| Darin Petkov | 9ce452b | 2010-11-17 14:33:28 -0800 | [diff] [blame] | 545 |   virtual void TransferTerminated(HttpFetcher* fetcher) { | 
 | 546 |     ADD_FAILURE(); | 
 | 547 |   } | 
| rspangler@google.com | 49fdf18 | 2009-10-10 00:57:34 +0000 | [diff] [blame] | 548 |   void Unpause() { | 
 | 549 |     CHECK(paused_); | 
 | 550 |     paused_ = false; | 
 | 551 |     fetcher_->Unpause(); | 
| rspangler@google.com | 49fdf18 | 2009-10-10 00:57:34 +0000 | [diff] [blame] | 552 |   } | 
 | 553 |   bool paused_; | 
 | 554 |   HttpFetcher* fetcher_; | 
 | 555 |   GMainLoop* loop_; | 
 | 556 | }; | 
 | 557 |  | 
 | 558 | gboolean UnpausingTimeoutCallback(gpointer data) { | 
 | 559 |   PausingHttpFetcherTestDelegate *delegate = | 
 | 560 |       reinterpret_cast<PausingHttpFetcherTestDelegate*>(data); | 
 | 561 |   if (delegate->paused_) | 
 | 562 |     delegate->Unpause(); | 
 | 563 |   return TRUE; | 
 | 564 | } | 
 | 565 | }  // namespace {} | 
 | 566 |  | 
 | 567 | TYPED_TEST(HttpFetcherTest, PauseTest) { | 
| Andrew de los Reyes | 9bbd187 | 2010-07-16 14:52:29 -0700 | [diff] [blame] | 568 |   GMainLoop* loop = g_main_loop_new(g_main_context_default(), FALSE); | 
| rspangler@google.com | 49fdf18 | 2009-10-10 00:57:34 +0000 | [diff] [blame] | 569 |   { | 
 | 570 |     PausingHttpFetcherTestDelegate delegate; | 
| Gilad Arnold | 9bedeb5 | 2011-11-17 16:19:57 -0800 | [diff] [blame] | 571 |     scoped_ptr<HttpFetcher> fetcher(this->test_.NewLargeFetcher()); | 
| rspangler@google.com | 49fdf18 | 2009-10-10 00:57:34 +0000 | [diff] [blame] | 572 |     delegate.paused_ = false; | 
 | 573 |     delegate.loop_ = loop; | 
 | 574 |     delegate.fetcher_ = fetcher.get(); | 
 | 575 |     fetcher->set_delegate(&delegate); | 
 | 576 |  | 
| Jay Srinivasan | 4348879 | 2012-06-19 00:25:31 -0700 | [diff] [blame] | 577 |     MockConnectionManager* mock_cm = dynamic_cast<MockConnectionManager*>( | 
| Jay Srinivasan | 6f6ea00 | 2012-12-14 11:26:28 -0800 | [diff] [blame] | 578 |         fetcher->GetSystemState()->connection_manager()); | 
| Jay Srinivasan | 4348879 | 2012-06-19 00:25:31 -0700 | [diff] [blame] | 579 |     EXPECT_CALL(*mock_cm, GetConnectionType(_,_)) | 
 | 580 |       .WillRepeatedly(DoAll(SetArgumentPointee<1>(kNetCellular), Return(true))); | 
 | 581 |     EXPECT_CALL(*mock_cm, IsUpdateAllowedOver(kNetCellular)) | 
 | 582 |       .WillRepeatedly(Return(true)); | 
 | 583 |     EXPECT_CALL(*mock_cm, StringForConnectionType(kNetCellular)) | 
 | 584 |       .WillRepeatedly(Return(flimflam::kTypeCellular)); | 
 | 585 |  | 
| Gilad Arnold | 9bedeb5 | 2011-11-17 16:19:57 -0800 | [diff] [blame] | 586 |     scoped_ptr<HttpServer> server(this->test_.CreateServer()); | 
 | 587 |     ASSERT_TRUE(server->started_); | 
| Andrew de los Reyes | f3ed8e7 | 2011-02-16 10:35:46 -0800 | [diff] [blame] | 588 |  | 
| Gilad Arnold | 9bedeb5 | 2011-11-17 16:19:57 -0800 | [diff] [blame] | 589 |     guint callback_id = g_timeout_add(kHttpResponseInternalServerError, | 
 | 590 |                                       UnpausingTimeoutCallback, &delegate); | 
| Gilad Arnold | b6c562a | 2013-07-01 02:19:26 -0700 | [diff] [blame] | 591 |     fetcher->BeginTransfer(this->test_.BigUrl(server->GetPort())); | 
| rspangler@google.com | 49fdf18 | 2009-10-10 00:57:34 +0000 | [diff] [blame] | 592 |  | 
 | 593 |     g_main_loop_run(loop); | 
| Andrew de los Reyes | f3ed8e7 | 2011-02-16 10:35:46 -0800 | [diff] [blame] | 594 |     g_source_remove(callback_id); | 
| rspangler@google.com | 49fdf18 | 2009-10-10 00:57:34 +0000 | [diff] [blame] | 595 |   } | 
 | 596 |   g_main_loop_unref(loop); | 
 | 597 | } | 
 | 598 |  | 
 | 599 | namespace { | 
 | 600 | class AbortingHttpFetcherTestDelegate : public HttpFetcherDelegate { | 
 | 601 |  public: | 
 | 602 |   virtual void ReceivedBytes(HttpFetcher* fetcher, | 
 | 603 |                              const char* bytes, int length) {} | 
 | 604 |   virtual void TransferComplete(HttpFetcher* fetcher, bool successful) { | 
| Darin Petkov | 9ce452b | 2010-11-17 14:33:28 -0800 | [diff] [blame] | 605 |     ADD_FAILURE();  // We should never get here | 
| rspangler@google.com | 49fdf18 | 2009-10-10 00:57:34 +0000 | [diff] [blame] | 606 |     g_main_loop_quit(loop_); | 
 | 607 |   } | 
| Darin Petkov | 9ce452b | 2010-11-17 14:33:28 -0800 | [diff] [blame] | 608 |   virtual void TransferTerminated(HttpFetcher* fetcher) { | 
 | 609 |     EXPECT_EQ(fetcher, fetcher_.get()); | 
 | 610 |     EXPECT_FALSE(once_); | 
 | 611 |     EXPECT_TRUE(callback_once_); | 
 | 612 |     callback_once_ = false; | 
 | 613 |     // |fetcher| can be destroyed during this callback. | 
 | 614 |     fetcher_.reset(NULL); | 
| Andrew de los Reyes | 819fef2 | 2010-12-17 11:33:58 -0800 | [diff] [blame] | 615 |   } | 
| rspangler@google.com | 49fdf18 | 2009-10-10 00:57:34 +0000 | [diff] [blame] | 616 |   void TerminateTransfer() { | 
 | 617 |     CHECK(once_); | 
 | 618 |     once_ = false; | 
 | 619 |     fetcher_->TerminateTransfer(); | 
 | 620 |   } | 
 | 621 |   void EndLoop() { | 
 | 622 |     g_main_loop_quit(loop_); | 
 | 623 |   } | 
 | 624 |   bool once_; | 
| Darin Petkov | 9ce452b | 2010-11-17 14:33:28 -0800 | [diff] [blame] | 625 |   bool callback_once_; | 
 | 626 |   scoped_ptr<HttpFetcher> fetcher_; | 
| rspangler@google.com | 49fdf18 | 2009-10-10 00:57:34 +0000 | [diff] [blame] | 627 |   GMainLoop* loop_; | 
 | 628 | }; | 
 | 629 |  | 
 | 630 | gboolean AbortingTimeoutCallback(gpointer data) { | 
 | 631 |   AbortingHttpFetcherTestDelegate *delegate = | 
 | 632 |       reinterpret_cast<AbortingHttpFetcherTestDelegate*>(data); | 
 | 633 |   if (delegate->once_) { | 
 | 634 |     delegate->TerminateTransfer(); | 
 | 635 |     return TRUE; | 
 | 636 |   } else { | 
 | 637 |     delegate->EndLoop(); | 
 | 638 |     return FALSE; | 
 | 639 |   } | 
 | 640 | } | 
 | 641 | }  // namespace {} | 
 | 642 |  | 
 | 643 | TYPED_TEST(HttpFetcherTest, AbortTest) { | 
| Andrew de los Reyes | 9bbd187 | 2010-07-16 14:52:29 -0700 | [diff] [blame] | 644 |   GMainLoop* loop = g_main_loop_new(g_main_context_default(), FALSE); | 
| rspangler@google.com | 49fdf18 | 2009-10-10 00:57:34 +0000 | [diff] [blame] | 645 |   { | 
 | 646 |     AbortingHttpFetcherTestDelegate delegate; | 
| Gilad Arnold | 9bedeb5 | 2011-11-17 16:19:57 -0800 | [diff] [blame] | 647 |     delegate.fetcher_.reset(this->test_.NewLargeFetcher()); | 
| rspangler@google.com | 49fdf18 | 2009-10-10 00:57:34 +0000 | [diff] [blame] | 648 |     delegate.once_ = true; | 
| Darin Petkov | 9ce452b | 2010-11-17 14:33:28 -0800 | [diff] [blame] | 649 |     delegate.callback_once_ = true; | 
| rspangler@google.com | 49fdf18 | 2009-10-10 00:57:34 +0000 | [diff] [blame] | 650 |     delegate.loop_ = loop; | 
| Darin Petkov | 9ce452b | 2010-11-17 14:33:28 -0800 | [diff] [blame] | 651 |     delegate.fetcher_->set_delegate(&delegate); | 
| rspangler@google.com | 49fdf18 | 2009-10-10 00:57:34 +0000 | [diff] [blame] | 652 |  | 
| Jay Srinivasan | 4348879 | 2012-06-19 00:25:31 -0700 | [diff] [blame] | 653 |     MockConnectionManager* mock_cm = dynamic_cast<MockConnectionManager*>( | 
| Jay Srinivasan | 6f6ea00 | 2012-12-14 11:26:28 -0800 | [diff] [blame] | 654 |         delegate.fetcher_->GetSystemState()->connection_manager()); | 
| Jay Srinivasan | 4348879 | 2012-06-19 00:25:31 -0700 | [diff] [blame] | 655 |     EXPECT_CALL(*mock_cm, GetConnectionType(_,_)) | 
 | 656 |       .WillRepeatedly(DoAll(SetArgumentPointee<1>(kNetWifi), Return(true))); | 
 | 657 |     EXPECT_CALL(*mock_cm, IsUpdateAllowedOver(kNetWifi)) | 
 | 658 |       .WillRepeatedly(Return(true)); | 
 | 659 |     EXPECT_CALL(*mock_cm, StringForConnectionType(kNetWifi)) | 
 | 660 |       .WillRepeatedly(Return(flimflam::kTypeWifi)); | 
 | 661 |  | 
| Gilad Arnold | 9bedeb5 | 2011-11-17 16:19:57 -0800 | [diff] [blame] | 662 |     scoped_ptr<HttpServer> server(this->test_.CreateServer()); | 
 | 663 |     this->test_.IgnoreServerAborting(server.get()); | 
 | 664 |     ASSERT_TRUE(server->started_); | 
 | 665 |  | 
| rspangler@google.com | 49fdf18 | 2009-10-10 00:57:34 +0000 | [diff] [blame] | 666 |     GSource* timeout_source_; | 
 | 667 |     timeout_source_ = g_timeout_source_new(0);  // ms | 
 | 668 |     g_source_set_callback(timeout_source_, AbortingTimeoutCallback, &delegate, | 
 | 669 |                           NULL); | 
 | 670 |     g_source_attach(timeout_source_, NULL); | 
| Gilad Arnold | b6c562a | 2013-07-01 02:19:26 -0700 | [diff] [blame] | 671 |     delegate.fetcher_->BeginTransfer(this->test_.BigUrl(server->GetPort())); | 
| rspangler@google.com | 49fdf18 | 2009-10-10 00:57:34 +0000 | [diff] [blame] | 672 |  | 
 | 673 |     g_main_loop_run(loop); | 
| Darin Petkov | 9ce452b | 2010-11-17 14:33:28 -0800 | [diff] [blame] | 674 |     CHECK(!delegate.once_); | 
 | 675 |     CHECK(!delegate.callback_once_); | 
| rspangler@google.com | 49fdf18 | 2009-10-10 00:57:34 +0000 | [diff] [blame] | 676 |     g_source_destroy(timeout_source_); | 
 | 677 |   } | 
 | 678 |   g_main_loop_unref(loop); | 
 | 679 | } | 
 | 680 |  | 
| adlr@google.com | c98a7ed | 2009-12-04 18:54:03 +0000 | [diff] [blame] | 681 | namespace { | 
 | 682 | class FlakyHttpFetcherTestDelegate : public HttpFetcherDelegate { | 
 | 683 |  public: | 
 | 684 |   virtual void ReceivedBytes(HttpFetcher* fetcher, | 
 | 685 |                              const char* bytes, int length) { | 
 | 686 |     data.append(bytes, length); | 
 | 687 |   } | 
 | 688 |   virtual void TransferComplete(HttpFetcher* fetcher, bool successful) { | 
| Andrew de los Reyes | fb4ad7d | 2010-07-19 10:43:46 -0700 | [diff] [blame] | 689 |     EXPECT_TRUE(successful); | 
| Gilad Arnold | 9bedeb5 | 2011-11-17 16:19:57 -0800 | [diff] [blame] | 690 |     EXPECT_EQ(kHttpResponsePartialContent, fetcher->http_response_code()); | 
| adlr@google.com | c98a7ed | 2009-12-04 18:54:03 +0000 | [diff] [blame] | 691 |     g_main_loop_quit(loop_); | 
 | 692 |   } | 
| Darin Petkov | 9ce452b | 2010-11-17 14:33:28 -0800 | [diff] [blame] | 693 |   virtual void TransferTerminated(HttpFetcher* fetcher) { | 
 | 694 |     ADD_FAILURE(); | 
 | 695 |   } | 
| adlr@google.com | c98a7ed | 2009-12-04 18:54:03 +0000 | [diff] [blame] | 696 |   string data; | 
 | 697 |   GMainLoop* loop_; | 
 | 698 | }; | 
 | 699 | }  // namespace {} | 
 | 700 |  | 
 | 701 | TYPED_TEST(HttpFetcherTest, FlakyTest) { | 
| Gilad Arnold | 9bedeb5 | 2011-11-17 16:19:57 -0800 | [diff] [blame] | 702 |   if (this->test_.IsMock()) | 
| adlr@google.com | c98a7ed | 2009-12-04 18:54:03 +0000 | [diff] [blame] | 703 |     return; | 
| Andrew de los Reyes | 9bbd187 | 2010-07-16 14:52:29 -0700 | [diff] [blame] | 704 |   GMainLoop* loop = g_main_loop_new(g_main_context_default(), FALSE); | 
| adlr@google.com | c98a7ed | 2009-12-04 18:54:03 +0000 | [diff] [blame] | 705 |   { | 
 | 706 |     FlakyHttpFetcherTestDelegate delegate; | 
 | 707 |     delegate.loop_ = loop; | 
| Gilad Arnold | 9bedeb5 | 2011-11-17 16:19:57 -0800 | [diff] [blame] | 708 |     scoped_ptr<HttpFetcher> fetcher(this->test_.NewSmallFetcher()); | 
| adlr@google.com | c98a7ed | 2009-12-04 18:54:03 +0000 | [diff] [blame] | 709 |     fetcher->set_delegate(&delegate); | 
 | 710 |  | 
| Jay Srinivasan | 4348879 | 2012-06-19 00:25:31 -0700 | [diff] [blame] | 711 |     MockConnectionManager* mock_cm = dynamic_cast<MockConnectionManager*>( | 
| Jay Srinivasan | 6f6ea00 | 2012-12-14 11:26:28 -0800 | [diff] [blame] | 712 |         fetcher->GetSystemState()->connection_manager()); | 
| Jay Srinivasan | 4348879 | 2012-06-19 00:25:31 -0700 | [diff] [blame] | 713 |     EXPECT_CALL(*mock_cm, GetConnectionType(_,_)) | 
 | 714 |       .WillRepeatedly(DoAll(SetArgumentPointee<1>(kNetWifi), Return(true))); | 
 | 715 |     EXPECT_CALL(*mock_cm, IsUpdateAllowedOver(kNetWifi)) | 
 | 716 |       .WillRepeatedly(Return(true)); | 
 | 717 |     EXPECT_CALL(*mock_cm, StringForConnectionType(kNetWifi)) | 
 | 718 |       .WillRepeatedly(Return(flimflam::kTypeWifi)); | 
 | 719 |  | 
 | 720 |  | 
| Gilad Arnold | 9bedeb5 | 2011-11-17 16:19:57 -0800 | [diff] [blame] | 721 |     scoped_ptr<HttpServer> server(this->test_.CreateServer()); | 
 | 722 |     ASSERT_TRUE(server->started_); | 
| adlr@google.com | c98a7ed | 2009-12-04 18:54:03 +0000 | [diff] [blame] | 723 |  | 
 | 724 |     StartTransferArgs start_xfer_args = { | 
 | 725 |       fetcher.get(), | 
| Gilad Arnold | b6c562a | 2013-07-01 02:19:26 -0700 | [diff] [blame] | 726 |       LocalServerUrlForPath(server->GetPort(), | 
 | 727 |                             StringPrintf("/flaky/%d/%d/%d/%d", kBigLength, | 
| Gilad Arnold | 9bedeb5 | 2011-11-17 16:19:57 -0800 | [diff] [blame] | 728 |                                          kFlakyTruncateLength, | 
 | 729 |                                          kFlakySleepEvery, | 
 | 730 |                                          kFlakySleepSecs)) | 
| adlr@google.com | c98a7ed | 2009-12-04 18:54:03 +0000 | [diff] [blame] | 731 |     }; | 
 | 732 |  | 
 | 733 |     g_timeout_add(0, StartTransfer, &start_xfer_args); | 
 | 734 |     g_main_loop_run(loop); | 
 | 735 |  | 
 | 736 |     // verify the data we get back | 
| Gilad Arnold | 9bedeb5 | 2011-11-17 16:19:57 -0800 | [diff] [blame] | 737 |     ASSERT_EQ(kBigLength, delegate.data.size()); | 
 | 738 |     for (int i = 0; i < kBigLength; i += 10) { | 
| adlr@google.com | c98a7ed | 2009-12-04 18:54:03 +0000 | [diff] [blame] | 739 |       // Assert so that we don't flood the screen w/ EXPECT errors on failure. | 
 | 740 |       ASSERT_EQ(delegate.data.substr(i, 10), "abcdefghij"); | 
 | 741 |     } | 
 | 742 |   } | 
 | 743 |   g_main_loop_unref(loop); | 
 | 744 | } | 
 | 745 |  | 
| Andrew de los Reyes | 9bbd187 | 2010-07-16 14:52:29 -0700 | [diff] [blame] | 746 | namespace { | 
 | 747 | class FailureHttpFetcherTestDelegate : public HttpFetcherDelegate { | 
 | 748 |  public: | 
| Jay Srinivasan | 135a58b | 2012-07-13 12:46:49 -0700 | [diff] [blame] | 749 |   FailureHttpFetcherTestDelegate(PythonHttpServer* server) | 
 | 750 |       : loop_(NULL), | 
 | 751 |         server_(server) {} | 
 | 752 |  | 
 | 753 |   virtual ~FailureHttpFetcherTestDelegate() { | 
 | 754 |     if (server_) { | 
 | 755 |       LOG(INFO) << "Stopping server in destructor"; | 
 | 756 |       delete server_; | 
 | 757 |       LOG(INFO) << "server stopped"; | 
 | 758 |     } | 
 | 759 |   } | 
 | 760 |  | 
| Andrew de los Reyes | 9bbd187 | 2010-07-16 14:52:29 -0700 | [diff] [blame] | 761 |   virtual void ReceivedBytes(HttpFetcher* fetcher, | 
 | 762 |                              const char* bytes, int length) { | 
 | 763 |     if (server_) { | 
| Jay Srinivasan | 135a58b | 2012-07-13 12:46:49 -0700 | [diff] [blame] | 764 |       LOG(INFO) << "Stopping server in ReceivedBytes"; | 
| Andrew de los Reyes | 9bbd187 | 2010-07-16 14:52:29 -0700 | [diff] [blame] | 765 |       delete server_; | 
 | 766 |       LOG(INFO) << "server stopped"; | 
 | 767 |       server_ = NULL; | 
 | 768 |     } | 
 | 769 |   } | 
 | 770 |   virtual void TransferComplete(HttpFetcher* fetcher, bool successful) { | 
 | 771 |     EXPECT_FALSE(successful); | 
| Darin Petkov | cb46621 | 2010-08-26 09:40:11 -0700 | [diff] [blame] | 772 |     EXPECT_EQ(0, fetcher->http_response_code()); | 
| Andrew de los Reyes | 9bbd187 | 2010-07-16 14:52:29 -0700 | [diff] [blame] | 773 |     g_main_loop_quit(loop_); | 
 | 774 |   } | 
| Darin Petkov | 9ce452b | 2010-11-17 14:33:28 -0800 | [diff] [blame] | 775 |   virtual void TransferTerminated(HttpFetcher* fetcher) { | 
 | 776 |     ADD_FAILURE(); | 
 | 777 |   } | 
| Andrew de los Reyes | 9bbd187 | 2010-07-16 14:52:29 -0700 | [diff] [blame] | 778 |   GMainLoop* loop_; | 
 | 779 |   PythonHttpServer* server_; | 
 | 780 | }; | 
 | 781 | }  // namespace {} | 
 | 782 |  | 
 | 783 |  | 
 | 784 | TYPED_TEST(HttpFetcherTest, FailureTest) { | 
| Gilad Arnold | 9bedeb5 | 2011-11-17 16:19:57 -0800 | [diff] [blame] | 785 |   if (this->test_.IsMock()) | 
| Andrew de los Reyes | 9bbd187 | 2010-07-16 14:52:29 -0700 | [diff] [blame] | 786 |     return; | 
 | 787 |   GMainLoop* loop = g_main_loop_new(g_main_context_default(), FALSE); | 
 | 788 |   { | 
| Jay Srinivasan | 135a58b | 2012-07-13 12:46:49 -0700 | [diff] [blame] | 789 |     FailureHttpFetcherTestDelegate delegate(NULL); | 
| Andrew de los Reyes | 9bbd187 | 2010-07-16 14:52:29 -0700 | [diff] [blame] | 790 |     delegate.loop_ = loop; | 
| Gilad Arnold | 9bedeb5 | 2011-11-17 16:19:57 -0800 | [diff] [blame] | 791 |     scoped_ptr<HttpFetcher> fetcher(this->test_.NewSmallFetcher()); | 
| Andrew de los Reyes | 9bbd187 | 2010-07-16 14:52:29 -0700 | [diff] [blame] | 792 |     fetcher->set_delegate(&delegate); | 
 | 793 |  | 
| Jay Srinivasan | 4348879 | 2012-06-19 00:25:31 -0700 | [diff] [blame] | 794 |     MockConnectionManager* mock_cm = dynamic_cast<MockConnectionManager*>( | 
| Jay Srinivasan | 6f6ea00 | 2012-12-14 11:26:28 -0800 | [diff] [blame] | 795 |         fetcher->GetSystemState()->connection_manager()); | 
| Jay Srinivasan | 4348879 | 2012-06-19 00:25:31 -0700 | [diff] [blame] | 796 |     EXPECT_CALL(*mock_cm, GetConnectionType(_,_)) | 
 | 797 |       .WillRepeatedly(DoAll(SetArgumentPointee<1>(kNetEthernet), Return(true))); | 
 | 798 |     EXPECT_CALL(*mock_cm, IsUpdateAllowedOver(kNetEthernet)) | 
 | 799 |       .WillRepeatedly(Return(true)); | 
 | 800 |     EXPECT_CALL(*mock_cm, StringForConnectionType(kNetEthernet)) | 
 | 801 |       .WillRepeatedly(Return(flimflam::kTypeEthernet)); | 
 | 802 |  | 
 | 803 |  | 
| Andrew de los Reyes | 9bbd187 | 2010-07-16 14:52:29 -0700 | [diff] [blame] | 804 |     StartTransferArgs start_xfer_args = { | 
 | 805 |       fetcher.get(), | 
| Gilad Arnold | b6c562a | 2013-07-01 02:19:26 -0700 | [diff] [blame] | 806 |       LocalServerUrlForPath(0, this->test_.SmallUrl(0)) | 
| Andrew de los Reyes | 9bbd187 | 2010-07-16 14:52:29 -0700 | [diff] [blame] | 807 |     }; | 
 | 808 |  | 
 | 809 |     g_timeout_add(0, StartTransfer, &start_xfer_args); | 
 | 810 |     g_main_loop_run(loop); | 
 | 811 |  | 
 | 812 |     // Exiting and testing happens in the delegate | 
 | 813 |   } | 
 | 814 |   g_main_loop_unref(loop); | 
 | 815 | } | 
 | 816 |  | 
 | 817 | TYPED_TEST(HttpFetcherTest, ServerDiesTest) { | 
| Gilad Arnold | 9bedeb5 | 2011-11-17 16:19:57 -0800 | [diff] [blame] | 818 |   if (this->test_.IsMock()) | 
| Andrew de los Reyes | 9bbd187 | 2010-07-16 14:52:29 -0700 | [diff] [blame] | 819 |     return; | 
 | 820 |   GMainLoop* loop = g_main_loop_new(g_main_context_default(), FALSE); | 
 | 821 |   { | 
| Jay Srinivasan | 135a58b | 2012-07-13 12:46:49 -0700 | [diff] [blame] | 822 |     FailureHttpFetcherTestDelegate delegate(new PythonHttpServer); | 
| Andrew de los Reyes | 9bbd187 | 2010-07-16 14:52:29 -0700 | [diff] [blame] | 823 |     delegate.loop_ = loop; | 
| Gilad Arnold | 9bedeb5 | 2011-11-17 16:19:57 -0800 | [diff] [blame] | 824 |     scoped_ptr<HttpFetcher> fetcher(this->test_.NewSmallFetcher()); | 
| Andrew de los Reyes | 9bbd187 | 2010-07-16 14:52:29 -0700 | [diff] [blame] | 825 |     fetcher->set_delegate(&delegate); | 
 | 826 |  | 
 | 827 |     StartTransferArgs start_xfer_args = { | 
 | 828 |       fetcher.get(), | 
| Gilad Arnold | b6c562a | 2013-07-01 02:19:26 -0700 | [diff] [blame] | 829 |       LocalServerUrlForPath(0, | 
 | 830 |                             StringPrintf("/flaky/%d/%d/%d/%d", kBigLength, | 
| Gilad Arnold | 9bedeb5 | 2011-11-17 16:19:57 -0800 | [diff] [blame] | 831 |                                          kFlakyTruncateLength, | 
 | 832 |                                          kFlakySleepEvery, | 
 | 833 |                                          kFlakySleepSecs)) | 
| Andrew de los Reyes | 9bbd187 | 2010-07-16 14:52:29 -0700 | [diff] [blame] | 834 |     }; | 
 | 835 |  | 
 | 836 |     g_timeout_add(0, StartTransfer, &start_xfer_args); | 
 | 837 |     g_main_loop_run(loop); | 
 | 838 |  | 
 | 839 |     // Exiting and testing happens in the delegate | 
 | 840 |   } | 
 | 841 |   g_main_loop_unref(loop); | 
 | 842 | } | 
 | 843 |  | 
| Darin Petkov | 41c2fcf | 2010-08-25 13:14:48 -0700 | [diff] [blame] | 844 | namespace { | 
| Gilad Arnold | 9bedeb5 | 2011-11-17 16:19:57 -0800 | [diff] [blame] | 845 | const HttpResponseCode kRedirectCodes[] = { | 
 | 846 |   kHttpResponseMovedPermanently, kHttpResponseFound, kHttpResponseSeeOther, | 
 | 847 |   kHttpResponseTempRedirect | 
 | 848 | }; | 
| Darin Petkov | 41c2fcf | 2010-08-25 13:14:48 -0700 | [diff] [blame] | 849 |  | 
 | 850 | class RedirectHttpFetcherTestDelegate : public HttpFetcherDelegate { | 
 | 851 |  public: | 
 | 852 |   RedirectHttpFetcherTestDelegate(bool expected_successful) | 
 | 853 |       : expected_successful_(expected_successful) {} | 
 | 854 |   virtual void ReceivedBytes(HttpFetcher* fetcher, | 
 | 855 |                              const char* bytes, int length) { | 
 | 856 |     data.append(bytes, length); | 
 | 857 |   } | 
 | 858 |   virtual void TransferComplete(HttpFetcher* fetcher, bool successful) { | 
 | 859 |     EXPECT_EQ(expected_successful_, successful); | 
| Darin Petkov | cb46621 | 2010-08-26 09:40:11 -0700 | [diff] [blame] | 860 |     if (expected_successful_) | 
| Gilad Arnold | 9bedeb5 | 2011-11-17 16:19:57 -0800 | [diff] [blame] | 861 |       EXPECT_EQ(kHttpResponseOk, fetcher->http_response_code()); | 
| Darin Petkov | cb46621 | 2010-08-26 09:40:11 -0700 | [diff] [blame] | 862 |     else { | 
| Gilad Arnold | 9bedeb5 | 2011-11-17 16:19:57 -0800 | [diff] [blame] | 863 |       EXPECT_GE(fetcher->http_response_code(), kHttpResponseMovedPermanently); | 
 | 864 |       EXPECT_LE(fetcher->http_response_code(), kHttpResponseTempRedirect); | 
| Darin Petkov | cb46621 | 2010-08-26 09:40:11 -0700 | [diff] [blame] | 865 |     } | 
| Darin Petkov | 41c2fcf | 2010-08-25 13:14:48 -0700 | [diff] [blame] | 866 |     g_main_loop_quit(loop_); | 
 | 867 |   } | 
| Darin Petkov | 9ce452b | 2010-11-17 14:33:28 -0800 | [diff] [blame] | 868 |   virtual void TransferTerminated(HttpFetcher* fetcher) { | 
 | 869 |     ADD_FAILURE(); | 
 | 870 |   } | 
| Darin Petkov | 41c2fcf | 2010-08-25 13:14:48 -0700 | [diff] [blame] | 871 |   bool expected_successful_; | 
 | 872 |   string data; | 
 | 873 |   GMainLoop* loop_; | 
 | 874 | }; | 
 | 875 |  | 
 | 876 | // RedirectTest takes ownership of |http_fetcher|. | 
| Gilad Arnold | b6c562a | 2013-07-01 02:19:26 -0700 | [diff] [blame] | 877 | void RedirectTest(const HttpServer* server, | 
 | 878 |                   bool expected_successful, | 
| Darin Petkov | 41c2fcf | 2010-08-25 13:14:48 -0700 | [diff] [blame] | 879 |                   const string& url, | 
 | 880 |                   HttpFetcher* http_fetcher) { | 
 | 881 |   GMainLoop* loop = g_main_loop_new(g_main_context_default(), FALSE); | 
| Jay Srinivasan | 135a58b | 2012-07-13 12:46:49 -0700 | [diff] [blame] | 882 |   { | 
 | 883 |     RedirectHttpFetcherTestDelegate delegate(expected_successful); | 
 | 884 |     delegate.loop_ = loop; | 
 | 885 |     scoped_ptr<HttpFetcher> fetcher(http_fetcher); | 
 | 886 |     fetcher->set_delegate(&delegate); | 
| Darin Petkov | 41c2fcf | 2010-08-25 13:14:48 -0700 | [diff] [blame] | 887 |  | 
| Jay Srinivasan | 135a58b | 2012-07-13 12:46:49 -0700 | [diff] [blame] | 888 |     MockConnectionManager* mock_cm = dynamic_cast<MockConnectionManager*>( | 
| Jay Srinivasan | 6f6ea00 | 2012-12-14 11:26:28 -0800 | [diff] [blame] | 889 |         fetcher->GetSystemState()->connection_manager()); | 
| Jay Srinivasan | 135a58b | 2012-07-13 12:46:49 -0700 | [diff] [blame] | 890 |     EXPECT_CALL(*mock_cm, GetConnectionType(_,_)) | 
 | 891 |       .WillRepeatedly(DoAll(SetArgumentPointee<1>(kNetEthernet), Return(true))); | 
 | 892 |     EXPECT_CALL(*mock_cm, IsUpdateAllowedOver(kNetEthernet)) | 
 | 893 |       .WillRepeatedly(Return(true)); | 
 | 894 |     EXPECT_CALL(*mock_cm, StringForConnectionType(kNetEthernet)) | 
 | 895 |       .WillRepeatedly(Return(flimflam::kTypeEthernet)); | 
| Jay Srinivasan | 4348879 | 2012-06-19 00:25:31 -0700 | [diff] [blame] | 896 |  | 
| Jay Srinivasan | 135a58b | 2012-07-13 12:46:49 -0700 | [diff] [blame] | 897 |     StartTransferArgs start_xfer_args = | 
| Gilad Arnold | b6c562a | 2013-07-01 02:19:26 -0700 | [diff] [blame] | 898 |         { fetcher.get(), LocalServerUrlForPath(server->GetPort(), url) }; | 
| Darin Petkov | 41c2fcf | 2010-08-25 13:14:48 -0700 | [diff] [blame] | 899 |  | 
| Jay Srinivasan | 135a58b | 2012-07-13 12:46:49 -0700 | [diff] [blame] | 900 |     g_timeout_add(0, StartTransfer, &start_xfer_args); | 
 | 901 |     g_main_loop_run(loop); | 
 | 902 |     if (expected_successful) { | 
 | 903 |       // verify the data we get back | 
 | 904 |       ASSERT_EQ(kMediumLength, delegate.data.size()); | 
 | 905 |       for (int i = 0; i < kMediumLength; i += 10) { | 
 | 906 |         // Assert so that we don't flood the screen w/ EXPECT errors on failure. | 
 | 907 |         ASSERT_EQ(delegate.data.substr(i, 10), "abcdefghij"); | 
 | 908 |       } | 
| Darin Petkov | 41c2fcf | 2010-08-25 13:14:48 -0700 | [diff] [blame] | 909 |     } | 
 | 910 |   } | 
 | 911 |   g_main_loop_unref(loop); | 
 | 912 | } | 
 | 913 | }  // namespace {} | 
 | 914 |  | 
 | 915 | TYPED_TEST(HttpFetcherTest, SimpleRedirectTest) { | 
| Gilad Arnold | 9bedeb5 | 2011-11-17 16:19:57 -0800 | [diff] [blame] | 916 |   if (this->test_.IsMock()) | 
| Darin Petkov | 41c2fcf | 2010-08-25 13:14:48 -0700 | [diff] [blame] | 917 |     return; | 
| Gilad Arnold | 9bedeb5 | 2011-11-17 16:19:57 -0800 | [diff] [blame] | 918 |  | 
 | 919 |   scoped_ptr<HttpServer> server(this->test_.CreateServer()); | 
 | 920 |   ASSERT_TRUE(server->started_); | 
 | 921 |  | 
| Darin Petkov | 41c2fcf | 2010-08-25 13:14:48 -0700 | [diff] [blame] | 922 |   for (size_t c = 0; c < arraysize(kRedirectCodes); ++c) { | 
| Gilad Arnold | 9bedeb5 | 2011-11-17 16:19:57 -0800 | [diff] [blame] | 923 |     const string url = base::StringPrintf("/redirect/%d/download/%d", | 
 | 924 |                                           kRedirectCodes[c], | 
 | 925 |                                           kMediumLength); | 
| Gilad Arnold | b6c562a | 2013-07-01 02:19:26 -0700 | [diff] [blame] | 926 |     RedirectTest(server.get(), true, url, this->test_.NewLargeFetcher()); | 
| Darin Petkov | 41c2fcf | 2010-08-25 13:14:48 -0700 | [diff] [blame] | 927 |   } | 
 | 928 | } | 
 | 929 |  | 
 | 930 | TYPED_TEST(HttpFetcherTest, MaxRedirectTest) { | 
| Gilad Arnold | 9bedeb5 | 2011-11-17 16:19:57 -0800 | [diff] [blame] | 931 |   if (this->test_.IsMock()) | 
| Darin Petkov | 41c2fcf | 2010-08-25 13:14:48 -0700 | [diff] [blame] | 932 |     return; | 
| Gilad Arnold | 9bedeb5 | 2011-11-17 16:19:57 -0800 | [diff] [blame] | 933 |  | 
 | 934 |   scoped_ptr<HttpServer> server(this->test_.CreateServer()); | 
 | 935 |   ASSERT_TRUE(server->started_); | 
 | 936 |  | 
| Darin Petkov | 41c2fcf | 2010-08-25 13:14:48 -0700 | [diff] [blame] | 937 |   string url; | 
 | 938 |   for (int r = 0; r < LibcurlHttpFetcher::kMaxRedirects; r++) { | 
 | 939 |     url += base::StringPrintf("/redirect/%d", | 
 | 940 |                               kRedirectCodes[r % arraysize(kRedirectCodes)]); | 
 | 941 |   } | 
| Gilad Arnold | 9bedeb5 | 2011-11-17 16:19:57 -0800 | [diff] [blame] | 942 |   url += base::StringPrintf("/download/%d", kMediumLength); | 
| Gilad Arnold | b6c562a | 2013-07-01 02:19:26 -0700 | [diff] [blame] | 943 |   RedirectTest(server.get(), true, url, this->test_.NewLargeFetcher()); | 
| Darin Petkov | 41c2fcf | 2010-08-25 13:14:48 -0700 | [diff] [blame] | 944 | } | 
 | 945 |  | 
 | 946 | TYPED_TEST(HttpFetcherTest, BeyondMaxRedirectTest) { | 
| Gilad Arnold | 9bedeb5 | 2011-11-17 16:19:57 -0800 | [diff] [blame] | 947 |   if (this->test_.IsMock()) | 
| Darin Petkov | 41c2fcf | 2010-08-25 13:14:48 -0700 | [diff] [blame] | 948 |     return; | 
| Gilad Arnold | 9bedeb5 | 2011-11-17 16:19:57 -0800 | [diff] [blame] | 949 |  | 
 | 950 |   scoped_ptr<HttpServer> server(this->test_.CreateServer()); | 
 | 951 |   ASSERT_TRUE(server->started_); | 
 | 952 |  | 
| Darin Petkov | 41c2fcf | 2010-08-25 13:14:48 -0700 | [diff] [blame] | 953 |   string url; | 
 | 954 |   for (int r = 0; r < LibcurlHttpFetcher::kMaxRedirects + 1; r++) { | 
 | 955 |     url += base::StringPrintf("/redirect/%d", | 
 | 956 |                               kRedirectCodes[r % arraysize(kRedirectCodes)]); | 
 | 957 |   } | 
| Gilad Arnold | 9bedeb5 | 2011-11-17 16:19:57 -0800 | [diff] [blame] | 958 |   url += base::StringPrintf("/download/%d", kMediumLength); | 
| Gilad Arnold | b6c562a | 2013-07-01 02:19:26 -0700 | [diff] [blame] | 959 |   RedirectTest(server.get(), false, url, this->test_.NewLargeFetcher()); | 
| Darin Petkov | 41c2fcf | 2010-08-25 13:14:48 -0700 | [diff] [blame] | 960 | } | 
 | 961 |  | 
| Andrew de los Reyes | 3fd5d30 | 2010-10-07 20:07:18 -0700 | [diff] [blame] | 962 | namespace { | 
 | 963 | class MultiHttpFetcherTestDelegate : public HttpFetcherDelegate { | 
 | 964 |  public: | 
 | 965 |   MultiHttpFetcherTestDelegate(int expected_response_code) | 
 | 966 |       : expected_response_code_(expected_response_code) {} | 
| Gilad Arnold | e4ad250 | 2011-12-29 17:08:54 -0800 | [diff] [blame] | 967 |  | 
| Andrew de los Reyes | 3fd5d30 | 2010-10-07 20:07:18 -0700 | [diff] [blame] | 968 |   virtual void ReceivedBytes(HttpFetcher* fetcher, | 
 | 969 |                              const char* bytes, int length) { | 
| Darin Petkov | 9ce452b | 2010-11-17 14:33:28 -0800 | [diff] [blame] | 970 |     EXPECT_EQ(fetcher, fetcher_.get()); | 
| Andrew de los Reyes | 3fd5d30 | 2010-10-07 20:07:18 -0700 | [diff] [blame] | 971 |     data.append(bytes, length); | 
 | 972 |   } | 
| Gilad Arnold | e4ad250 | 2011-12-29 17:08:54 -0800 | [diff] [blame] | 973 |  | 
| Andrew de los Reyes | 3fd5d30 | 2010-10-07 20:07:18 -0700 | [diff] [blame] | 974 |   virtual void TransferComplete(HttpFetcher* fetcher, bool successful) { | 
| Darin Petkov | 9ce452b | 2010-11-17 14:33:28 -0800 | [diff] [blame] | 975 |     EXPECT_EQ(fetcher, fetcher_.get()); | 
| Gilad Arnold | 9bedeb5 | 2011-11-17 16:19:57 -0800 | [diff] [blame] | 976 |     EXPECT_EQ(expected_response_code_ != kHttpResponseUndefined, successful); | 
| Andrew de los Reyes | 3fd5d30 | 2010-10-07 20:07:18 -0700 | [diff] [blame] | 977 |     if (expected_response_code_ != 0) | 
 | 978 |       EXPECT_EQ(expected_response_code_, fetcher->http_response_code()); | 
| Darin Petkov | 9ce452b | 2010-11-17 14:33:28 -0800 | [diff] [blame] | 979 |     // Destroy the fetcher (because we're allowed to). | 
 | 980 |     fetcher_.reset(NULL); | 
| Andrew de los Reyes | 3fd5d30 | 2010-10-07 20:07:18 -0700 | [diff] [blame] | 981 |     g_main_loop_quit(loop_); | 
 | 982 |   } | 
| Gilad Arnold | e4ad250 | 2011-12-29 17:08:54 -0800 | [diff] [blame] | 983 |  | 
| Darin Petkov | 9ce452b | 2010-11-17 14:33:28 -0800 | [diff] [blame] | 984 |   virtual void TransferTerminated(HttpFetcher* fetcher) { | 
 | 985 |     ADD_FAILURE(); | 
 | 986 |   } | 
| Gilad Arnold | e4ad250 | 2011-12-29 17:08:54 -0800 | [diff] [blame] | 987 |  | 
| Darin Petkov | 9ce452b | 2010-11-17 14:33:28 -0800 | [diff] [blame] | 988 |   scoped_ptr<HttpFetcher> fetcher_; | 
| Andrew de los Reyes | 3fd5d30 | 2010-10-07 20:07:18 -0700 | [diff] [blame] | 989 |   int expected_response_code_; | 
 | 990 |   string data; | 
 | 991 |   GMainLoop* loop_; | 
 | 992 | }; | 
 | 993 |  | 
 | 994 | void MultiTest(HttpFetcher* fetcher_in, | 
 | 995 |                const string& url, | 
| Andrew de los Reyes | 819fef2 | 2010-12-17 11:33:58 -0800 | [diff] [blame] | 996 |                const vector<pair<off_t, off_t> >& ranges, | 
| Andrew de los Reyes | 3fd5d30 | 2010-10-07 20:07:18 -0700 | [diff] [blame] | 997 |                const string& expected_prefix, | 
 | 998 |                off_t expected_size, | 
| Gilad Arnold | 9bedeb5 | 2011-11-17 16:19:57 -0800 | [diff] [blame] | 999 |                HttpResponseCode expected_response_code) { | 
| Andrew de los Reyes | 3fd5d30 | 2010-10-07 20:07:18 -0700 | [diff] [blame] | 1000 |   GMainLoop* loop = g_main_loop_new(g_main_context_default(), FALSE); | 
 | 1001 |   { | 
 | 1002 |     MultiHttpFetcherTestDelegate delegate(expected_response_code); | 
 | 1003 |     delegate.loop_ = loop; | 
| Darin Petkov | 9ce452b | 2010-11-17 14:33:28 -0800 | [diff] [blame] | 1004 |     delegate.fetcher_.reset(fetcher_in); | 
| Jay Srinivasan | 4348879 | 2012-06-19 00:25:31 -0700 | [diff] [blame] | 1005 |  | 
 | 1006 |     MockConnectionManager* mock_cm = dynamic_cast<MockConnectionManager*>( | 
| Jay Srinivasan | 6f6ea00 | 2012-12-14 11:26:28 -0800 | [diff] [blame] | 1007 |         fetcher_in->GetSystemState()->connection_manager()); | 
| Jay Srinivasan | 4348879 | 2012-06-19 00:25:31 -0700 | [diff] [blame] | 1008 |     EXPECT_CALL(*mock_cm, GetConnectionType(_,_)) | 
 | 1009 |       .WillRepeatedly(DoAll(SetArgumentPointee<1>(kNetWifi), Return(true))); | 
 | 1010 |     EXPECT_CALL(*mock_cm, IsUpdateAllowedOver(kNetWifi)) | 
 | 1011 |       .WillRepeatedly(Return(true)); | 
 | 1012 |     EXPECT_CALL(*mock_cm, StringForConnectionType(kNetWifi)) | 
 | 1013 |       .WillRepeatedly(Return(flimflam::kTypeWifi)); | 
 | 1014 |  | 
| Gilad Arnold | 9bedeb5 | 2011-11-17 16:19:57 -0800 | [diff] [blame] | 1015 |     MultiRangeHttpFetcher* multi_fetcher = | 
 | 1016 |         dynamic_cast<MultiRangeHttpFetcher*>(fetcher_in); | 
| Andrew de los Reyes | 3fd5d30 | 2010-10-07 20:07:18 -0700 | [diff] [blame] | 1017 |     ASSERT_TRUE(multi_fetcher); | 
| Andrew de los Reyes | 819fef2 | 2010-12-17 11:33:58 -0800 | [diff] [blame] | 1018 |     multi_fetcher->ClearRanges(); | 
 | 1019 |     for (vector<pair<off_t, off_t> >::const_iterator it = ranges.begin(), | 
 | 1020 |              e = ranges.end(); it != e; ++it) { | 
| Gilad Arnold | e4ad250 | 2011-12-29 17:08:54 -0800 | [diff] [blame] | 1021 |       std::string tmp_str = StringPrintf("%jd+", it->first); | 
 | 1022 |       if (it->second > 0) { | 
 | 1023 |         base::StringAppendF(&tmp_str, "%jd", it->second); | 
 | 1024 |         multi_fetcher->AddRange(it->first, it->second); | 
 | 1025 |       } else { | 
 | 1026 |         base::StringAppendF(&tmp_str, "?"); | 
 | 1027 |         multi_fetcher->AddRange(it->first); | 
 | 1028 |       } | 
 | 1029 |       LOG(INFO) << "added range: " << tmp_str; | 
| Andrew de los Reyes | 819fef2 | 2010-12-17 11:33:58 -0800 | [diff] [blame] | 1030 |     } | 
| Darin Petkov | fc7a0ce | 2010-10-25 10:38:37 -0700 | [diff] [blame] | 1031 |     multi_fetcher->SetBuildType(false); | 
| Darin Petkov | 9ce452b | 2010-11-17 14:33:28 -0800 | [diff] [blame] | 1032 |     multi_fetcher->set_delegate(&delegate); | 
| Andrew de los Reyes | 3fd5d30 | 2010-10-07 20:07:18 -0700 | [diff] [blame] | 1033 |  | 
| Darin Petkov | 9ce452b | 2010-11-17 14:33:28 -0800 | [diff] [blame] | 1034 |     StartTransferArgs start_xfer_args = {multi_fetcher, url}; | 
| Andrew de los Reyes | 3fd5d30 | 2010-10-07 20:07:18 -0700 | [diff] [blame] | 1035 |  | 
 | 1036 |     g_timeout_add(0, StartTransfer, &start_xfer_args); | 
 | 1037 |     g_main_loop_run(loop); | 
 | 1038 |  | 
 | 1039 |     EXPECT_EQ(expected_size, delegate.data.size()); | 
 | 1040 |     EXPECT_EQ(expected_prefix, | 
 | 1041 |               string(delegate.data.data(), expected_prefix.size())); | 
 | 1042 |   } | 
 | 1043 |   g_main_loop_unref(loop); | 
 | 1044 | } | 
 | 1045 | }  // namespace {} | 
 | 1046 |  | 
| Darin Petkov | 9ce452b | 2010-11-17 14:33:28 -0800 | [diff] [blame] | 1047 | TYPED_TEST(HttpFetcherTest, MultiHttpFetcherSimpleTest) { | 
| Gilad Arnold | 9bedeb5 | 2011-11-17 16:19:57 -0800 | [diff] [blame] | 1048 |   if (!this->test_.IsMulti()) | 
| Andrew de los Reyes | 3fd5d30 | 2010-10-07 20:07:18 -0700 | [diff] [blame] | 1049 |     return; | 
| Gilad Arnold | 9bedeb5 | 2011-11-17 16:19:57 -0800 | [diff] [blame] | 1050 |  | 
 | 1051 |   scoped_ptr<HttpServer> server(this->test_.CreateServer()); | 
 | 1052 |   ASSERT_TRUE(server->started_); | 
| Andrew de los Reyes | 3fd5d30 | 2010-10-07 20:07:18 -0700 | [diff] [blame] | 1053 |  | 
| Andrew de los Reyes | 819fef2 | 2010-12-17 11:33:58 -0800 | [diff] [blame] | 1054 |   vector<pair<off_t, off_t> > ranges; | 
| Andrew de los Reyes | 3fd5d30 | 2010-10-07 20:07:18 -0700 | [diff] [blame] | 1055 |   ranges.push_back(make_pair(0, 25)); | 
| Gilad Arnold | e4ad250 | 2011-12-29 17:08:54 -0800 | [diff] [blame] | 1056 |   ranges.push_back(make_pair(99, 0)); | 
| Gilad Arnold | 9bedeb5 | 2011-11-17 16:19:57 -0800 | [diff] [blame] | 1057 |   MultiTest(this->test_.NewLargeFetcher(), | 
| Gilad Arnold | b6c562a | 2013-07-01 02:19:26 -0700 | [diff] [blame] | 1058 |             this->test_.BigUrl(server->GetPort()), | 
| Andrew de los Reyes | 3fd5d30 | 2010-10-07 20:07:18 -0700 | [diff] [blame] | 1059 |             ranges, | 
 | 1060 |             "abcdefghijabcdefghijabcdejabcdefghijabcdef", | 
| Gilad Arnold | 9bedeb5 | 2011-11-17 16:19:57 -0800 | [diff] [blame] | 1061 |             kBigLength - (99 - 25), | 
 | 1062 |             kHttpResponsePartialContent); | 
| Andrew de los Reyes | 3fd5d30 | 2010-10-07 20:07:18 -0700 | [diff] [blame] | 1063 | } | 
 | 1064 |  | 
 | 1065 | TYPED_TEST(HttpFetcherTest, MultiHttpFetcherLengthLimitTest) { | 
| Gilad Arnold | 9bedeb5 | 2011-11-17 16:19:57 -0800 | [diff] [blame] | 1066 |   if (!this->test_.IsMulti()) | 
| Andrew de los Reyes | 3fd5d30 | 2010-10-07 20:07:18 -0700 | [diff] [blame] | 1067 |     return; | 
| Gilad Arnold | 9bedeb5 | 2011-11-17 16:19:57 -0800 | [diff] [blame] | 1068 |  | 
 | 1069 |   scoped_ptr<HttpServer> server(this->test_.CreateServer()); | 
 | 1070 |   ASSERT_TRUE(server->started_); | 
| Andrew de los Reyes | 3fd5d30 | 2010-10-07 20:07:18 -0700 | [diff] [blame] | 1071 |  | 
| Andrew de los Reyes | 819fef2 | 2010-12-17 11:33:58 -0800 | [diff] [blame] | 1072 |   vector<pair<off_t, off_t> > ranges; | 
| Andrew de los Reyes | 3fd5d30 | 2010-10-07 20:07:18 -0700 | [diff] [blame] | 1073 |   ranges.push_back(make_pair(0, 24)); | 
| Gilad Arnold | 9bedeb5 | 2011-11-17 16:19:57 -0800 | [diff] [blame] | 1074 |   MultiTest(this->test_.NewLargeFetcher(), | 
| Gilad Arnold | b6c562a | 2013-07-01 02:19:26 -0700 | [diff] [blame] | 1075 |             this->test_.BigUrl(server->GetPort()), | 
| Andrew de los Reyes | 3fd5d30 | 2010-10-07 20:07:18 -0700 | [diff] [blame] | 1076 |             ranges, | 
 | 1077 |             "abcdefghijabcdefghijabcd", | 
 | 1078 |             24, | 
| Gilad Arnold | e4ad250 | 2011-12-29 17:08:54 -0800 | [diff] [blame] | 1079 |             kHttpResponsePartialContent); | 
| Andrew de los Reyes | 3fd5d30 | 2010-10-07 20:07:18 -0700 | [diff] [blame] | 1080 | } | 
 | 1081 |  | 
 | 1082 | TYPED_TEST(HttpFetcherTest, MultiHttpFetcherMultiEndTest) { | 
| Gilad Arnold | 9bedeb5 | 2011-11-17 16:19:57 -0800 | [diff] [blame] | 1083 |   if (!this->test_.IsMulti()) | 
| Andrew de los Reyes | 3fd5d30 | 2010-10-07 20:07:18 -0700 | [diff] [blame] | 1084 |     return; | 
| Gilad Arnold | 9bedeb5 | 2011-11-17 16:19:57 -0800 | [diff] [blame] | 1085 |  | 
 | 1086 |   scoped_ptr<HttpServer> server(this->test_.CreateServer()); | 
 | 1087 |   ASSERT_TRUE(server->started_); | 
| Andrew de los Reyes | 3fd5d30 | 2010-10-07 20:07:18 -0700 | [diff] [blame] | 1088 |  | 
| Andrew de los Reyes | 819fef2 | 2010-12-17 11:33:58 -0800 | [diff] [blame] | 1089 |   vector<pair<off_t, off_t> > ranges; | 
| Gilad Arnold | e4ad250 | 2011-12-29 17:08:54 -0800 | [diff] [blame] | 1090 |   ranges.push_back(make_pair(kBigLength - 2, 0)); | 
 | 1091 |   ranges.push_back(make_pair(kBigLength - 3, 0)); | 
| Gilad Arnold | 9bedeb5 | 2011-11-17 16:19:57 -0800 | [diff] [blame] | 1092 |   MultiTest(this->test_.NewLargeFetcher(), | 
| Gilad Arnold | b6c562a | 2013-07-01 02:19:26 -0700 | [diff] [blame] | 1093 |             this->test_.BigUrl(server->GetPort()), | 
| Andrew de los Reyes | 3fd5d30 | 2010-10-07 20:07:18 -0700 | [diff] [blame] | 1094 |             ranges, | 
 | 1095 |             "ijhij", | 
 | 1096 |             5, | 
| Gilad Arnold | 9bedeb5 | 2011-11-17 16:19:57 -0800 | [diff] [blame] | 1097 |             kHttpResponsePartialContent); | 
| Andrew de los Reyes | 3fd5d30 | 2010-10-07 20:07:18 -0700 | [diff] [blame] | 1098 | } | 
 | 1099 |  | 
 | 1100 | TYPED_TEST(HttpFetcherTest, MultiHttpFetcherInsufficientTest) { | 
| Gilad Arnold | 9bedeb5 | 2011-11-17 16:19:57 -0800 | [diff] [blame] | 1101 |   if (!this->test_.IsMulti()) | 
| Andrew de los Reyes | 3fd5d30 | 2010-10-07 20:07:18 -0700 | [diff] [blame] | 1102 |     return; | 
| Gilad Arnold | 9bedeb5 | 2011-11-17 16:19:57 -0800 | [diff] [blame] | 1103 |  | 
 | 1104 |   scoped_ptr<HttpServer> server(this->test_.CreateServer()); | 
 | 1105 |   ASSERT_TRUE(server->started_); | 
| Andrew de los Reyes | 3fd5d30 | 2010-10-07 20:07:18 -0700 | [diff] [blame] | 1106 |  | 
| Andrew de los Reyes | 819fef2 | 2010-12-17 11:33:58 -0800 | [diff] [blame] | 1107 |   vector<pair<off_t, off_t> > ranges; | 
| Gilad Arnold | 9bedeb5 | 2011-11-17 16:19:57 -0800 | [diff] [blame] | 1108 |   ranges.push_back(make_pair(kBigLength - 2, 4)); | 
| Andrew de los Reyes | 3fd5d30 | 2010-10-07 20:07:18 -0700 | [diff] [blame] | 1109 |   for (int i = 0; i < 2; ++i) { | 
| Andrew de los Reyes | 819fef2 | 2010-12-17 11:33:58 -0800 | [diff] [blame] | 1110 |     LOG(INFO) << "i = " << i; | 
| Gilad Arnold | 9bedeb5 | 2011-11-17 16:19:57 -0800 | [diff] [blame] | 1111 |     MultiTest(this->test_.NewLargeFetcher(), | 
| Gilad Arnold | b6c562a | 2013-07-01 02:19:26 -0700 | [diff] [blame] | 1112 |               this->test_.BigUrl(server->GetPort()), | 
| Andrew de los Reyes | 3fd5d30 | 2010-10-07 20:07:18 -0700 | [diff] [blame] | 1113 |               ranges, | 
 | 1114 |               "ij", | 
 | 1115 |               2, | 
| Gilad Arnold | 9bedeb5 | 2011-11-17 16:19:57 -0800 | [diff] [blame] | 1116 |               kHttpResponseUndefined); | 
| Andrew de los Reyes | 3fd5d30 | 2010-10-07 20:07:18 -0700 | [diff] [blame] | 1117 |     ranges.push_back(make_pair(0, 5)); | 
 | 1118 |   } | 
 | 1119 | } | 
 | 1120 |  | 
| Gilad Arnold | 9bedeb5 | 2011-11-17 16:19:57 -0800 | [diff] [blame] | 1121 | // Issue #18143: when a fetch of a secondary chunk out of a chain, then it | 
 | 1122 | // should retry with other proxies listed before giving up. | 
 | 1123 | // | 
 | 1124 | // (1) successful recovery: The offset fetch will fail twice but succeed with | 
 | 1125 | // the third proxy. | 
 | 1126 | TYPED_TEST(HttpFetcherTest, MultiHttpFetcherErrorIfOffsetRecoverableTest) { | 
 | 1127 |   if (!this->test_.IsMulti()) | 
 | 1128 |     return; | 
 | 1129 |  | 
 | 1130 |   scoped_ptr<HttpServer> server(this->test_.CreateServer()); | 
 | 1131 |   ASSERT_TRUE(server->started_); | 
 | 1132 |  | 
 | 1133 |   vector<pair<off_t, off_t> > ranges; | 
 | 1134 |   ranges.push_back(make_pair(0, 25)); | 
| Gilad Arnold | e4ad250 | 2011-12-29 17:08:54 -0800 | [diff] [blame] | 1135 |   ranges.push_back(make_pair(99, 0)); | 
| Gilad Arnold | 9bedeb5 | 2011-11-17 16:19:57 -0800 | [diff] [blame] | 1136 |   MultiTest(this->test_.NewLargeFetcher(3), | 
| Gilad Arnold | b6c562a | 2013-07-01 02:19:26 -0700 | [diff] [blame] | 1137 |             LocalServerUrlForPath(server->GetPort(), | 
 | 1138 |                                   base::StringPrintf("/error-if-offset/%d/2", | 
| Gilad Arnold | 9bedeb5 | 2011-11-17 16:19:57 -0800 | [diff] [blame] | 1139 |                                                      kBigLength)), | 
 | 1140 |             ranges, | 
 | 1141 |             "abcdefghijabcdefghijabcdejabcdefghijabcdef", | 
 | 1142 |             kBigLength - (99 - 25), | 
 | 1143 |             kHttpResponsePartialContent); | 
 | 1144 | } | 
 | 1145 |  | 
 | 1146 | // (2) unsuccessful recovery: The offset fetch will fail repeatedly.  The | 
 | 1147 | // fetcher will signal a (failed) completed transfer to the delegate. | 
 | 1148 | TYPED_TEST(HttpFetcherTest, MultiHttpFetcherErrorIfOffsetUnrecoverableTest) { | 
 | 1149 |   if (!this->test_.IsMulti()) | 
 | 1150 |     return; | 
 | 1151 |  | 
 | 1152 |   scoped_ptr<HttpServer> server(this->test_.CreateServer()); | 
 | 1153 |   ASSERT_TRUE(server->started_); | 
 | 1154 |  | 
 | 1155 |   vector<pair<off_t, off_t> > ranges; | 
 | 1156 |   ranges.push_back(make_pair(0, 25)); | 
| Gilad Arnold | e4ad250 | 2011-12-29 17:08:54 -0800 | [diff] [blame] | 1157 |   ranges.push_back(make_pair(99, 0)); | 
| Gilad Arnold | 9bedeb5 | 2011-11-17 16:19:57 -0800 | [diff] [blame] | 1158 |   MultiTest(this->test_.NewLargeFetcher(2), | 
| Gilad Arnold | b6c562a | 2013-07-01 02:19:26 -0700 | [diff] [blame] | 1159 |             LocalServerUrlForPath(server->GetPort(), | 
 | 1160 |                                   base::StringPrintf("/error-if-offset/%d/3", | 
| Gilad Arnold | 9bedeb5 | 2011-11-17 16:19:57 -0800 | [diff] [blame] | 1161 |                                                      kBigLength)), | 
 | 1162 |             ranges, | 
 | 1163 |             "abcdefghijabcdefghijabcde",  // only received the first chunk | 
 | 1164 |             25, | 
 | 1165 |             kHttpResponseUndefined); | 
 | 1166 | } | 
 | 1167 |  | 
 | 1168 |  | 
 | 1169 |  | 
| Andrew de los Reyes | d57d147 | 2010-10-21 13:34:08 -0700 | [diff] [blame] | 1170 | namespace { | 
| Darin Petkov | fc7a0ce | 2010-10-25 10:38:37 -0700 | [diff] [blame] | 1171 | class BlockedTransferTestDelegate : public HttpFetcherDelegate { | 
| Andrew de los Reyes | d57d147 | 2010-10-21 13:34:08 -0700 | [diff] [blame] | 1172 |  public: | 
 | 1173 |   virtual void ReceivedBytes(HttpFetcher* fetcher, | 
 | 1174 |                              const char* bytes, int length) { | 
 | 1175 |     ADD_FAILURE(); | 
 | 1176 |   } | 
 | 1177 |   virtual void TransferComplete(HttpFetcher* fetcher, bool successful) { | 
 | 1178 |     EXPECT_FALSE(successful); | 
 | 1179 |     g_main_loop_quit(loop_); | 
 | 1180 |   } | 
| Darin Petkov | 9ce452b | 2010-11-17 14:33:28 -0800 | [diff] [blame] | 1181 |   virtual void TransferTerminated(HttpFetcher* fetcher) { | 
 | 1182 |     ADD_FAILURE(); | 
 | 1183 |   } | 
| Andrew de los Reyes | d57d147 | 2010-10-21 13:34:08 -0700 | [diff] [blame] | 1184 |   GMainLoop* loop_; | 
 | 1185 | }; | 
 | 1186 |  | 
 | 1187 | }  // namespace | 
 | 1188 |  | 
| Darin Petkov | fc7a0ce | 2010-10-25 10:38:37 -0700 | [diff] [blame] | 1189 | TYPED_TEST(HttpFetcherTest, BlockedTransferTest) { | 
| Gilad Arnold | 9bedeb5 | 2011-11-17 16:19:57 -0800 | [diff] [blame] | 1190 |   if (this->test_.IsMock() || this->test_.IsMulti()) | 
| Andrew de los Reyes | d57d147 | 2010-10-21 13:34:08 -0700 | [diff] [blame] | 1191 |     return; | 
| Andrew de los Reyes | d57d147 | 2010-10-21 13:34:08 -0700 | [diff] [blame] | 1192 |  | 
| Darin Petkov | fc7a0ce | 2010-10-25 10:38:37 -0700 | [diff] [blame] | 1193 |   for (int i = 0; i < 2; i++) { | 
| Gilad Arnold | 9bedeb5 | 2011-11-17 16:19:57 -0800 | [diff] [blame] | 1194 |     scoped_ptr<HttpServer> server(this->test_.CreateServer()); | 
 | 1195 |     ASSERT_TRUE(server->started_); | 
| Andrew de los Reyes | d57d147 | 2010-10-21 13:34:08 -0700 | [diff] [blame] | 1196 |  | 
| Darin Petkov | fc7a0ce | 2010-10-25 10:38:37 -0700 | [diff] [blame] | 1197 |     GMainLoop* loop = g_main_loop_new(g_main_context_default(), FALSE); | 
| Jay Srinivasan | 135a58b | 2012-07-13 12:46:49 -0700 | [diff] [blame] | 1198 |     { | 
 | 1199 |       BlockedTransferTestDelegate delegate; | 
 | 1200 |       delegate.loop_ = loop; | 
| Andrew de los Reyes | d57d147 | 2010-10-21 13:34:08 -0700 | [diff] [blame] | 1201 |  | 
| Jay Srinivasan | 135a58b | 2012-07-13 12:46:49 -0700 | [diff] [blame] | 1202 |       bool is_allowed = (i != 0); | 
 | 1203 |       scoped_ptr<HttpFetcher> fetcher(this->test_.NewLargeFetcher()); | 
 | 1204 |       MockConnectionManager* mock_cm = dynamic_cast<MockConnectionManager*>( | 
| Jay Srinivasan | 6f6ea00 | 2012-12-14 11:26:28 -0800 | [diff] [blame] | 1205 |           fetcher->GetSystemState()->connection_manager()); | 
| Jay Srinivasan | 135a58b | 2012-07-13 12:46:49 -0700 | [diff] [blame] | 1206 |       EXPECT_CALL(*mock_cm, GetConnectionType(_,_)) | 
 | 1207 |         .WillRepeatedly(DoAll(SetArgumentPointee<1>(kNetWifi), Return(true))); | 
 | 1208 |       EXPECT_CALL(*mock_cm, IsUpdateAllowedOver(kNetWifi)) | 
 | 1209 |         .WillRepeatedly(Return(is_allowed)); | 
 | 1210 |       EXPECT_CALL(*mock_cm, StringForConnectionType(kNetWifi)) | 
 | 1211 |         .WillRepeatedly(Return(flimflam::kTypeWifi)); | 
| Jay Srinivasan | 4348879 | 2012-06-19 00:25:31 -0700 | [diff] [blame] | 1212 |  | 
| Jay Srinivasan | 135a58b | 2012-07-13 12:46:49 -0700 | [diff] [blame] | 1213 |       bool is_official_build = (i == 1); | 
 | 1214 |       LOG(INFO) << "is_update_allowed_over_connection: " << is_allowed; | 
 | 1215 |       LOG(INFO) << "is_official_build: " << is_official_build; | 
 | 1216 |       fetcher->SetBuildType(is_official_build); | 
 | 1217 |       fetcher->set_delegate(&delegate); | 
| Darin Petkov | fc7a0ce | 2010-10-25 10:38:37 -0700 | [diff] [blame] | 1218 |  | 
| Jay Srinivasan | 135a58b | 2012-07-13 12:46:49 -0700 | [diff] [blame] | 1219 |       StartTransferArgs start_xfer_args = | 
| Gilad Arnold | b6c562a | 2013-07-01 02:19:26 -0700 | [diff] [blame] | 1220 |           {fetcher.get(), | 
 | 1221 |            LocalServerUrlForPath(server->GetPort(), | 
 | 1222 |                                  this->test_.SmallUrl(server->GetPort()))}; | 
| Darin Petkov | fc7a0ce | 2010-10-25 10:38:37 -0700 | [diff] [blame] | 1223 |  | 
| Jay Srinivasan | 135a58b | 2012-07-13 12:46:49 -0700 | [diff] [blame] | 1224 |       g_timeout_add(0, StartTransfer, &start_xfer_args); | 
 | 1225 |       g_main_loop_run(loop); | 
 | 1226 |     } | 
| Darin Petkov | fc7a0ce | 2010-10-25 10:38:37 -0700 | [diff] [blame] | 1227 |     g_main_loop_unref(loop); | 
 | 1228 |   } | 
| Andrew de los Reyes | d57d147 | 2010-10-21 13:34:08 -0700 | [diff] [blame] | 1229 | } | 
 | 1230 |  | 
| rspangler@google.com | 49fdf18 | 2009-10-10 00:57:34 +0000 | [diff] [blame] | 1231 | }  // namespace chromeos_update_engine |