blob: b6384113616af7901b90e049ab8c934161a1674f [file] [log] [blame]
Mike Frysinger8155d082012-04-06 15:23:18 -04001// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
rspangler@google.com49fdf182009-10-10 00:57:34 +00002// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include <unistd.h>
Darin Petkov41c2fcf2010-08-25 13:14:48 -07006
adlr@google.comc98a7ed2009-12-04 18:54:03 +00007#include <string>
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -07008#include <utility>
adlr@google.comc98a7ed2009-12-04 18:54:03 +00009#include <vector>
Darin Petkov41c2fcf2010-08-25 13:14:48 -070010
Andrew de los Reyes45168102010-11-22 11:13:50 -080011#include <base/logging.h>
Chris Masoned903c3b2011-05-12 15:35:46 -070012#include <base/memory/scoped_ptr.h>
Andrew de los Reyes45168102010-11-22 11:13:50 -080013#include <base/string_util.h>
Mike Frysinger8155d082012-04-06 15:23:18 -040014#include <base/stringprintf.h>
Gilad Arnold8e3f1262013-01-08 14:59:54 -080015#include <base/time.h>
Jay Srinivasan43488792012-06-19 00:25:31 -070016#include <chromeos/dbus/service_constants.h>
Andrew de los Reyes45168102010-11-22 11:13:50 -080017#include <glib.h>
18#include <gtest/gtest.h>
19
Gilad Arnold9bedeb52011-11-17 16:19:57 -080020#include "update_engine/http_common.h"
rspangler@google.com49fdf182009-10-10 00:57:34 +000021#include "update_engine/libcurl_http_fetcher.h"
Jay Srinivasan43488792012-06-19 00:25:31 -070022#include "update_engine/mock_connection_manager.h"
rspangler@google.com49fdf182009-10-10 00:57:34 +000023#include "update_engine/mock_http_fetcher.h"
Jay Srinivasan08fce042012-06-07 16:31:01 -070024#include "update_engine/mock_system_state.h"
Andrew de los Reyes819fef22010-12-17 11:33:58 -080025#include "update_engine/multi_range_http_fetcher.h"
Andrew de los Reyes45168102010-11-22 11:13:50 -080026#include "update_engine/proxy_resolver.h"
Jay Srinivasan08fce042012-06-07 16:31:01 -070027#include "update_engine/utils.h"
rspangler@google.com49fdf182009-10-10 00:57:34 +000028
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -070029using std::make_pair;
Andrew de los Reyes819fef22010-12-17 11:33:58 -080030using std::pair;
adlr@google.comc98a7ed2009-12-04 18:54:03 +000031using std::string;
32using std::vector;
33
Gilad Arnold8e3f1262013-01-08 14:59:54 -080034using base::TimeDelta;
Jay Srinivasan43488792012-06-19 00:25:31 -070035using testing::_;
36using testing::SetArgumentPointee;
37using testing::DoAll;
38using testing::Return;
39
Gilad Arnold9bedeb52011-11-17 16:19:57 -080040namespace {
41
42const int kBigLength = 100000;
43const int kMediumLength = 1000;
Gilad Arnold34bf1ee2012-02-09 16:16:02 -080044const int kFlakyTruncateLength = 29000;
45const int kFlakySleepEvery = 3;
Gilad Arnold9bedeb52011-11-17 16:19:57 -080046const int kFlakySleepSecs = 10;
47
Gilad Arnold97bdb3f2013-06-30 23:05:50 -070048const int kServerPort = 8088;
49
Gilad Arnold9bedeb52011-11-17 16:19:57 -080050} // namespace
51
rspangler@google.com49fdf182009-10-10 00:57:34 +000052namespace chromeos_update_engine {
53
Gilad Arnold9bedeb52011-11-17 16:19:57 -080054static const char *kUnusedUrl = "unused://unused";
55
56static inline string LocalServerUrlForPath(const string& path) {
Jay Srinivasan43488792012-06-19 00:25:31 -070057 return base::StringPrintf("http://127.0.0.1:%d%s", kServerPort, path.c_str());
rspangler@google.com49fdf182009-10-10 00:57:34 +000058}
59
Gilad Arnold9bedeb52011-11-17 16:19:57 -080060//
61// Class hierarchy for HTTP server implementations.
62//
63
64class HttpServer {
rspangler@google.com49fdf182009-10-10 00:57:34 +000065 public:
Gilad Arnold9bedeb52011-11-17 16:19:57 -080066 // This makes it an abstract class (dirty but works).
67 virtual ~HttpServer() = 0;
68
rspangler@google.com49fdf182009-10-10 00:57:34 +000069 bool started_;
70};
71
Gilad Arnold9bedeb52011-11-17 16:19:57 -080072HttpServer::~HttpServer() {}
rspangler@google.com49fdf182009-10-10 00:57:34 +000073
Gilad Arnold9bedeb52011-11-17 16:19:57 -080074
75class NullHttpServer : public HttpServer {
rspangler@google.com49fdf182009-10-10 00:57:34 +000076 public:
Gilad Arnold9bedeb52011-11-17 16:19:57 -080077 NullHttpServer() {
78 started_ = true;
rspangler@google.com49fdf182009-10-10 00:57:34 +000079 }
rspangler@google.com49fdf182009-10-10 00:57:34 +000080};
81
Gilad Arnold9bedeb52011-11-17 16:19:57 -080082
83class PythonHttpServer : public HttpServer {
rspangler@google.com49fdf182009-10-10 00:57:34 +000084 public:
85 PythonHttpServer() {
Gilad Arnold97bdb3f2013-06-30 23:05:50 -070086 char *port_str = NULL;
87 char *argv[] = {
88 strdup("./test_http_server"),
89 asprintf(&port_str, "%d", kServerPort) >= 0 ? port_str : NULL,
90 NULL};
rspangler@google.com49fdf182009-10-10 00:57:34 +000091 GError *err;
92 started_ = false;
Andrew de los Reyes08c4e272010-04-15 14:02:17 -070093 validate_quit_ = true;
rspangler@google.com49fdf182009-10-10 00:57:34 +000094 if (!g_spawn_async(NULL,
95 argv,
96 NULL,
97 G_SPAWN_DO_NOT_REAP_CHILD,
98 NULL,
99 NULL,
100 &pid_,
101 &err)) {
Jay Srinivasan135a58b2012-07-13 12:46:49 -0700102 LOG(INFO) << "unable to spawn http server process";
rspangler@google.com49fdf182009-10-10 00:57:34 +0000103 return;
104 }
Jay Srinivasan135a58b2012-07-13 12:46:49 -0700105 LOG(INFO) << "started http server with pid " << pid_;
rspangler@google.com49fdf182009-10-10 00:57:34 +0000106 int rc = 1;
Gilad Arnold8e3f1262013-01-08 14:59:54 -0800107 const TimeDelta kMaxSleep = TimeDelta::FromMinutes(60);
108 TimeDelta timeout = TimeDelta::FromMilliseconds(15);
Andrew de los Reyes3270f742010-07-15 22:28:14 -0700109 started_ = true;
Jay Srinivasan135a58b2012-07-13 12:46:49 -0700110 while (rc && timeout < kMaxSleep) {
111 // Wait before the first attempt also as it takes a while for the
112 // test_http_server to be ready.
Gilad Arnold8e3f1262013-01-08 14:59:54 -0800113 LOG(INFO) << "waiting for " << utils::FormatTimeDelta(timeout);
114 g_usleep(timeout.InMicroseconds());
Jay Srinivasan135a58b2012-07-13 12:46:49 -0700115 timeout *= 2;
116
Andrew de los Reyes3270f742010-07-15 22:28:14 -0700117 LOG(INFO) << "running wget to start";
Jay Srinivasan135a58b2012-07-13 12:46:49 -0700118 // rc should be 0 if we're able to successfully talk to the server.
rspangler@google.com49fdf182009-10-10 00:57:34 +0000119 rc = system((string("wget --output-document=/dev/null ") +
120 LocalServerUrlForPath("/test")).c_str());
Jay Srinivasan135a58b2012-07-13 12:46:49 -0700121 LOG(INFO) << "done running wget to start, rc = " << rc;
rspangler@google.com49fdf182009-10-10 00:57:34 +0000122 }
Jay Srinivasan135a58b2012-07-13 12:46:49 -0700123
124 if (rc) {
125 LOG(ERROR) << "Http server is not responding to wget.";
126 // TODO(jaysri): Currently we're overloading two things in
127 // started_ flag. One is that the process is running and other
128 // is that the process is responsive. We should separate these
129 // two so that we can do cleanup appropriately in each case.
130 started_ = false;
131 }
132
Gilad Arnold97bdb3f2013-06-30 23:05:50 -0700133 for (unsigned i = 0; i < arraysize(argv); i++)
134 free(argv[i]);
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -0700135 LOG(INFO) << "gdb attach now!";
rspangler@google.com49fdf182009-10-10 00:57:34 +0000136 }
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800137
rspangler@google.com49fdf182009-10-10 00:57:34 +0000138 ~PythonHttpServer() {
Jay Srinivasan135a58b2012-07-13 12:46:49 -0700139 if (!started_) {
140 LOG(INFO) << "not waiting for http server with pid " << pid_
141 << " to terminate, as it's not responding.";
142 // TODO(jaysri): Kill the process if it's really running but
143 // wgets or failing for some reason. Or if it's not running,
144 // add code to get rid of the defunct process.
rspangler@google.com49fdf182009-10-10 00:57:34 +0000145 return;
Jay Srinivasan135a58b2012-07-13 12:46:49 -0700146 }
147
rspangler@google.com49fdf182009-10-10 00:57:34 +0000148 // request that the server exit itself
Andrew de los Reyes3270f742010-07-15 22:28:14 -0700149 LOG(INFO) << "running wget to exit";
Andrew de los Reyes08c4e272010-04-15 14:02:17 -0700150 int rc = system((string("wget -t 1 --output-document=/dev/null ") +
Andrew de los Reyes9bbd1872010-07-16 14:52:29 -0700151 LocalServerUrlForPath("/quitquitquit")).c_str());
Andrew de los Reyes3270f742010-07-15 22:28:14 -0700152 LOG(INFO) << "done running wget to exit";
Andrew de los Reyes08c4e272010-04-15 14:02:17 -0700153 if (validate_quit_)
154 EXPECT_EQ(0, rc);
Jay Srinivasan135a58b2012-07-13 12:46:49 -0700155 LOG(INFO) << "waiting for http server with pid " << pid_ << " to terminate";
156 int status;
157 waitpid(pid_, &status, 0);
158 LOG(INFO) << "http server with pid " << pid_
159 << " terminated with status " << status;
rspangler@google.com49fdf182009-10-10 00:57:34 +0000160 }
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800161
rspangler@google.com49fdf182009-10-10 00:57:34 +0000162 GPid pid_;
Andrew de los Reyes08c4e272010-04-15 14:02:17 -0700163 bool validate_quit_;
rspangler@google.com49fdf182009-10-10 00:57:34 +0000164};
165
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800166//
167// Class hierarchy for HTTP fetcher test wrappers.
168//
169
170class AnyHttpFetcherTest {
rspangler@google.com49fdf182009-10-10 00:57:34 +0000171 public:
Jay Srinivasan43488792012-06-19 00:25:31 -0700172 AnyHttpFetcherTest()
173 : mock_connection_manager_(&mock_system_state_) {
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800174 mock_system_state_.set_connection_manager(&mock_connection_manager_);
Jay Srinivasan43488792012-06-19 00:25:31 -0700175 }
176
177 virtual HttpFetcher* NewLargeFetcher(size_t num_proxies) = 0;
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800178 HttpFetcher* NewLargeFetcher() {
179 return NewLargeFetcher(1);
180 }
181
182 virtual HttpFetcher* NewSmallFetcher(size_t num_proxies) = 0;
183 HttpFetcher* NewSmallFetcher() {
184 return NewSmallFetcher(1);
185 }
186
187 virtual string BigUrl() const { return kUnusedUrl; }
188 virtual string SmallUrl() const { return kUnusedUrl; }
189 virtual string ErrorUrl() const { return kUnusedUrl; }
190
191 virtual bool IsMock() const = 0;
192 virtual bool IsMulti() const = 0;
193
194 virtual void IgnoreServerAborting(HttpServer* server) const {}
195
196 virtual HttpServer *CreateServer() = 0;
197
198 protected:
199 DirectProxyResolver proxy_resolver_;
Jay Srinivasan43488792012-06-19 00:25:31 -0700200 MockSystemState mock_system_state_;
201 MockConnectionManager mock_connection_manager_;
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800202};
203
204class MockHttpFetcherTest : public AnyHttpFetcherTest {
205 public:
206 // Necessary to unhide the definition in the base class.
207 using AnyHttpFetcherTest::NewLargeFetcher;
208 virtual HttpFetcher* NewLargeFetcher(size_t num_proxies) {
209 vector<char> big_data(1000000);
210 CHECK(num_proxies > 0);
211 proxy_resolver_.set_num_proxies(num_proxies);
212 return new MockHttpFetcher(
213 big_data.data(),
214 big_data.size(),
215 reinterpret_cast<ProxyResolver*>(&proxy_resolver_));
216 }
217
218 // Necessary to unhide the definition in the base class.
219 using AnyHttpFetcherTest::NewSmallFetcher;
220 virtual HttpFetcher* NewSmallFetcher(size_t num_proxies) {
221 CHECK(num_proxies > 0);
222 proxy_resolver_.set_num_proxies(num_proxies);
223 return new MockHttpFetcher(
224 "x",
225 1,
226 reinterpret_cast<ProxyResolver*>(&proxy_resolver_));
227 }
228
229 virtual bool IsMock() const { return true; }
230 virtual bool IsMulti() const { return false; }
231
232 virtual HttpServer *CreateServer() {
233 return new NullHttpServer;
234 }
235};
236
237class LibcurlHttpFetcherTest : public AnyHttpFetcherTest {
238 public:
239 // Necessary to unhide the definition in the base class.
240 using AnyHttpFetcherTest::NewLargeFetcher;
241 virtual HttpFetcher* NewLargeFetcher(size_t num_proxies) {
242 CHECK(num_proxies > 0);
243 proxy_resolver_.set_num_proxies(num_proxies);
Andrew de los Reyes45168102010-11-22 11:13:50 -0800244 LibcurlHttpFetcher *ret = new
Jay Srinivasan08fce042012-06-07 16:31:01 -0700245 LibcurlHttpFetcher(reinterpret_cast<ProxyResolver*>(&proxy_resolver_),
Gilad Arnold7c04e762012-05-23 10:54:02 -0700246 &mock_system_state_, false);
Darin Petkovb83371f2010-08-17 09:34:49 -0700247 // Speed up test execution.
248 ret->set_idle_seconds(1);
249 ret->set_retry_seconds(1);
Darin Petkovfc7a0ce2010-10-25 10:38:37 -0700250 ret->SetBuildType(false);
rspangler@google.com49fdf182009-10-10 00:57:34 +0000251 return ret;
252 }
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800253
254 // Necessary to unhide the definition in the base class.
255 using AnyHttpFetcherTest::NewSmallFetcher;
256 virtual HttpFetcher* NewSmallFetcher(size_t num_proxies) {
257 return NewLargeFetcher(num_proxies);
rspangler@google.com49fdf182009-10-10 00:57:34 +0000258 }
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800259
260 virtual string BigUrl() const {
261 return LocalServerUrlForPath(base::StringPrintf("/download/%d",
262 kBigLength));
rspangler@google.com49fdf182009-10-10 00:57:34 +0000263 }
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800264 virtual string SmallUrl() const {
rspangler@google.com49fdf182009-10-10 00:57:34 +0000265 return LocalServerUrlForPath("/foo");
266 }
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800267 virtual string ErrorUrl() const {
Gilad Arnold48085ba2011-11-16 09:36:08 -0800268 return LocalServerUrlForPath("/error");
269 }
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800270
271 virtual bool IsMock() const { return false; }
272 virtual bool IsMulti() const { return false; }
273
274 virtual void IgnoreServerAborting(HttpServer* server) const {
Andrew de los Reyes08c4e272010-04-15 14:02:17 -0700275 PythonHttpServer *pyserver = reinterpret_cast<PythonHttpServer*>(server);
276 pyserver->validate_quit_ = false;
277 }
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800278
279 virtual HttpServer *CreateServer() {
280 return new PythonHttpServer;
281 }
rspangler@google.com49fdf182009-10-10 00:57:34 +0000282};
283
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800284class MultiRangeHttpFetcherTest : public LibcurlHttpFetcherTest {
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -0700285 public:
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800286 // Necessary to unhide the definition in the base class.
287 using AnyHttpFetcherTest::NewLargeFetcher;
288 virtual HttpFetcher* NewLargeFetcher(size_t num_proxies) {
289 CHECK(num_proxies > 0);
290 proxy_resolver_.set_num_proxies(num_proxies);
Andrew de los Reyes819fef22010-12-17 11:33:58 -0800291 ProxyResolver* resolver =
292 reinterpret_cast<ProxyResolver*>(&proxy_resolver_);
Gilad Arnold7c04e762012-05-23 10:54:02 -0700293 MultiRangeHttpFetcher *ret =
294 new MultiRangeHttpFetcher(
295 new LibcurlHttpFetcher(resolver, &mock_system_state_, false));
Andrew de los Reyes819fef22010-12-17 11:33:58 -0800296 ret->ClearRanges();
Gilad Arnolde4ad2502011-12-29 17:08:54 -0800297 ret->AddRange(0);
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -0700298 // Speed up test execution.
299 ret->set_idle_seconds(1);
300 ret->set_retry_seconds(1);
Darin Petkovfc7a0ce2010-10-25 10:38:37 -0700301 ret->SetBuildType(false);
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -0700302 return ret;
303 }
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800304
305 // Necessary to unhide the definition in the base class.
306 using AnyHttpFetcherTest::NewSmallFetcher;
307 virtual HttpFetcher* NewSmallFetcher(size_t num_proxies) {
308 return NewLargeFetcher(num_proxies);
309 }
310
311 virtual bool IsMulti() const { return true; }
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -0700312};
313
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800314
315//
316// Infrastructure for type tests of HTTP fetcher.
317// See: http://code.google.com/p/googletest/wiki/AdvancedGuide#Typed_Tests
318//
319
320// Fixture class template. We use an explicit constraint to guarantee that it
321// can only be instantiated with an AnyHttpFetcherTest type, see:
322// http://www2.research.att.com/~bs/bs_faq2.html#constraints
323template <typename T>
324class HttpFetcherTest : public ::testing::Test {
325 public:
326 T test_;
327
328 private:
329 static void TypeConstraint(T *a) {
330 AnyHttpFetcherTest *b = a;
Yunlian Jiang2dac5762013-04-12 09:53:09 -0700331 if (b == 0) // Silence compiler warning of unused variable.
332 *b = a;
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800333 }
334};
335
336// Test case types list.
337typedef ::testing::Types<LibcurlHttpFetcherTest,
338 MockHttpFetcherTest,
339 MultiRangeHttpFetcherTest> HttpFetcherTestTypes;
rspangler@google.com49fdf182009-10-10 00:57:34 +0000340TYPED_TEST_CASE(HttpFetcherTest, HttpFetcherTestTypes);
341
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800342
rspangler@google.com49fdf182009-10-10 00:57:34 +0000343namespace {
344class HttpFetcherTestDelegate : public HttpFetcherDelegate {
adlr@google.comc98a7ed2009-12-04 18:54:03 +0000345 public:
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800346 HttpFetcherTestDelegate() :
Gilad Arnold48085ba2011-11-16 09:36:08 -0800347 is_expect_error_(false), times_transfer_complete_called_(0),
348 times_transfer_terminated_called_(0), times_received_bytes_called_(0) {}
349
rspangler@google.com49fdf182009-10-10 00:57:34 +0000350 virtual void ReceivedBytes(HttpFetcher* fetcher,
351 const char* bytes, int length) {
352 char str[length + 1];
353 memset(str, 0, length + 1);
354 memcpy(str, bytes, length);
Gilad Arnold48085ba2011-11-16 09:36:08 -0800355
356 // Update counters
357 times_received_bytes_called_++;
rspangler@google.com49fdf182009-10-10 00:57:34 +0000358 }
Gilad Arnold48085ba2011-11-16 09:36:08 -0800359
rspangler@google.com49fdf182009-10-10 00:57:34 +0000360 virtual void TransferComplete(HttpFetcher* fetcher, bool successful) {
Gilad Arnold48085ba2011-11-16 09:36:08 -0800361 if (is_expect_error_)
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800362 EXPECT_EQ(kHttpResponseNotFound, fetcher->http_response_code());
Gilad Arnold48085ba2011-11-16 09:36:08 -0800363 else
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800364 EXPECT_EQ(kHttpResponseOk, fetcher->http_response_code());
rspangler@google.com49fdf182009-10-10 00:57:34 +0000365 g_main_loop_quit(loop_);
Gilad Arnold48085ba2011-11-16 09:36:08 -0800366
367 // Update counter
368 times_transfer_complete_called_++;
rspangler@google.com49fdf182009-10-10 00:57:34 +0000369 }
Gilad Arnold48085ba2011-11-16 09:36:08 -0800370
Darin Petkov9ce452b2010-11-17 14:33:28 -0800371 virtual void TransferTerminated(HttpFetcher* fetcher) {
372 ADD_FAILURE();
Gilad Arnold48085ba2011-11-16 09:36:08 -0800373 times_transfer_terminated_called_++;
Darin Petkov9ce452b2010-11-17 14:33:28 -0800374 }
Gilad Arnold48085ba2011-11-16 09:36:08 -0800375
rspangler@google.com49fdf182009-10-10 00:57:34 +0000376 GMainLoop* loop_;
Gilad Arnold48085ba2011-11-16 09:36:08 -0800377
378 // Are we expecting an error response? (default: no)
379 bool is_expect_error_;
380
381 // Counters for callback invocations.
382 int times_transfer_complete_called_;
383 int times_transfer_terminated_called_;
384 int times_received_bytes_called_;
rspangler@google.com49fdf182009-10-10 00:57:34 +0000385};
adlr@google.comc98a7ed2009-12-04 18:54:03 +0000386
387struct StartTransferArgs {
388 HttpFetcher *http_fetcher;
389 string url;
390};
391
392gboolean StartTransfer(gpointer data) {
393 StartTransferArgs *args = reinterpret_cast<StartTransferArgs*>(data);
394 args->http_fetcher->BeginTransfer(args->url);
395 return FALSE;
396}
rspangler@google.com49fdf182009-10-10 00:57:34 +0000397} // namespace {}
398
399TYPED_TEST(HttpFetcherTest, SimpleTest) {
Andrew de los Reyes9bbd1872010-07-16 14:52:29 -0700400 GMainLoop* loop = g_main_loop_new(g_main_context_default(), FALSE);
rspangler@google.com49fdf182009-10-10 00:57:34 +0000401 {
402 HttpFetcherTestDelegate delegate;
403 delegate.loop_ = loop;
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800404 scoped_ptr<HttpFetcher> fetcher(this->test_.NewSmallFetcher());
rspangler@google.com49fdf182009-10-10 00:57:34 +0000405 fetcher->set_delegate(&delegate);
406
Jay Srinivasan43488792012-06-19 00:25:31 -0700407 MockConnectionManager* mock_cm = dynamic_cast<MockConnectionManager*>(
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800408 fetcher->GetSystemState()->connection_manager());
Jay Srinivasan43488792012-06-19 00:25:31 -0700409 EXPECT_CALL(*mock_cm, GetConnectionType(_,_))
410 .WillRepeatedly(DoAll(SetArgumentPointee<1>(kNetWifi), Return(true)));
411 EXPECT_CALL(*mock_cm, IsUpdateAllowedOver(kNetWifi))
412 .WillRepeatedly(Return(true));
413 EXPECT_CALL(*mock_cm, StringForConnectionType(kNetWifi))
414 .WillRepeatedly(Return(flimflam::kTypeWifi));
415
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800416 scoped_ptr<HttpServer> server(this->test_.CreateServer());
417 ASSERT_TRUE(server->started_);
rspangler@google.com49fdf182009-10-10 00:57:34 +0000418
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800419 StartTransferArgs start_xfer_args = {fetcher.get(), this->test_.SmallUrl()};
adlr@google.comc98a7ed2009-12-04 18:54:03 +0000420
421 g_timeout_add(0, StartTransfer, &start_xfer_args);
rspangler@google.com49fdf182009-10-10 00:57:34 +0000422 g_main_loop_run(loop);
423 }
424 g_main_loop_unref(loop);
425}
426
Andrew de los Reyes3270f742010-07-15 22:28:14 -0700427TYPED_TEST(HttpFetcherTest, SimpleBigTest) {
Andrew de los Reyes9bbd1872010-07-16 14:52:29 -0700428 GMainLoop* loop = g_main_loop_new(g_main_context_default(), FALSE);
Andrew de los Reyes3270f742010-07-15 22:28:14 -0700429 {
430 HttpFetcherTestDelegate delegate;
431 delegate.loop_ = loop;
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800432 scoped_ptr<HttpFetcher> fetcher(this->test_.NewLargeFetcher());
Andrew de los Reyes3270f742010-07-15 22:28:14 -0700433 fetcher->set_delegate(&delegate);
434
Jay Srinivasan43488792012-06-19 00:25:31 -0700435 MockConnectionManager* mock_cm = dynamic_cast<MockConnectionManager*>(
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800436 fetcher->GetSystemState()->connection_manager());
Jay Srinivasan43488792012-06-19 00:25:31 -0700437 EXPECT_CALL(*mock_cm, GetConnectionType(_,_))
438 .WillRepeatedly(DoAll(SetArgumentPointee<1>(kNetEthernet), Return(true)));
439 EXPECT_CALL(*mock_cm, IsUpdateAllowedOver(kNetEthernet))
440 .WillRepeatedly(Return(true));
441 EXPECT_CALL(*mock_cm, StringForConnectionType(kNetEthernet))
442 .WillRepeatedly(Return(flimflam::kTypeEthernet));
443
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800444 scoped_ptr<HttpServer> server(this->test_.CreateServer());
445 ASSERT_TRUE(server->started_);
Andrew de los Reyes3270f742010-07-15 22:28:14 -0700446
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800447 StartTransferArgs start_xfer_args = {fetcher.get(), this->test_.BigUrl()};
Andrew de los Reyes3270f742010-07-15 22:28:14 -0700448
449 g_timeout_add(0, StartTransfer, &start_xfer_args);
450 g_main_loop_run(loop);
451 }
452 g_main_loop_unref(loop);
453}
454
Gilad Arnold48085ba2011-11-16 09:36:08 -0800455// Issue #9648: when server returns an error HTTP response, the fetcher needs to
456// terminate transfer prematurely, rather than try to process the error payload.
457TYPED_TEST(HttpFetcherTest, ErrorTest) {
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800458 if (this->test_.IsMock() || this->test_.IsMulti())
Gilad Arnold48085ba2011-11-16 09:36:08 -0800459 return;
460 GMainLoop* loop = g_main_loop_new(g_main_context_default(), FALSE);
461 {
462 HttpFetcherTestDelegate delegate;
463 delegate.loop_ = loop;
464
465 // Delegate should expect an error response.
466 delegate.is_expect_error_ = true;
467
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800468 scoped_ptr<HttpFetcher> fetcher(this->test_.NewSmallFetcher());
Gilad Arnold48085ba2011-11-16 09:36:08 -0800469 fetcher->set_delegate(&delegate);
470
Jay Srinivasan43488792012-06-19 00:25:31 -0700471 MockConnectionManager* mock_cm = dynamic_cast<MockConnectionManager*>(
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800472 fetcher->GetSystemState()->connection_manager());
Jay Srinivasan43488792012-06-19 00:25:31 -0700473 EXPECT_CALL(*mock_cm, GetConnectionType(_,_))
474 .WillRepeatedly(DoAll(SetArgumentPointee<1>(kNetWimax), Return(true)));
475 EXPECT_CALL(*mock_cm, IsUpdateAllowedOver(kNetWimax))
476 .WillRepeatedly(Return(true));
477 EXPECT_CALL(*mock_cm, StringForConnectionType(kNetWimax))
478 .WillRepeatedly(Return(flimflam::kTypeWimax));
479
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800480 scoped_ptr<HttpServer> server(this->test_.CreateServer());
481 ASSERT_TRUE(server->started_);
Gilad Arnold48085ba2011-11-16 09:36:08 -0800482
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800483 StartTransferArgs start_xfer_args = {
484 fetcher.get(),
485 this->test_.ErrorUrl()
486 };
Gilad Arnold48085ba2011-11-16 09:36:08 -0800487
488 g_timeout_add(0, StartTransfer, &start_xfer_args);
489 g_main_loop_run(loop);
490
491 // Make sure that no bytes were received.
492 CHECK_EQ(delegate.times_received_bytes_called_, 0);
Mike Frysinger0f9547d2012-02-16 12:11:37 -0500493 CHECK_EQ(fetcher->GetBytesDownloaded(), static_cast<size_t>(0));
Gilad Arnold48085ba2011-11-16 09:36:08 -0800494
495 // Make sure that transfer completion was signaled once, and no termination
496 // was signaled.
497 CHECK_EQ(delegate.times_transfer_complete_called_, 1);
498 CHECK_EQ(delegate.times_transfer_terminated_called_, 0);
499 }
500 g_main_loop_unref(loop);
501}
502
rspangler@google.com49fdf182009-10-10 00:57:34 +0000503namespace {
504class PausingHttpFetcherTestDelegate : public HttpFetcherDelegate {
505 public:
506 virtual void ReceivedBytes(HttpFetcher* fetcher,
507 const char* bytes, int length) {
508 char str[length + 1];
rspangler@google.com49fdf182009-10-10 00:57:34 +0000509 memset(str, 0, length + 1);
510 memcpy(str, bytes, length);
511 CHECK(!paused_);
512 paused_ = true;
513 fetcher->Pause();
rspangler@google.com49fdf182009-10-10 00:57:34 +0000514 }
515 virtual void TransferComplete(HttpFetcher* fetcher, bool successful) {
516 g_main_loop_quit(loop_);
517 }
Darin Petkov9ce452b2010-11-17 14:33:28 -0800518 virtual void TransferTerminated(HttpFetcher* fetcher) {
519 ADD_FAILURE();
520 }
rspangler@google.com49fdf182009-10-10 00:57:34 +0000521 void Unpause() {
522 CHECK(paused_);
523 paused_ = false;
524 fetcher_->Unpause();
rspangler@google.com49fdf182009-10-10 00:57:34 +0000525 }
526 bool paused_;
527 HttpFetcher* fetcher_;
528 GMainLoop* loop_;
529};
530
531gboolean UnpausingTimeoutCallback(gpointer data) {
532 PausingHttpFetcherTestDelegate *delegate =
533 reinterpret_cast<PausingHttpFetcherTestDelegate*>(data);
534 if (delegate->paused_)
535 delegate->Unpause();
536 return TRUE;
537}
538} // namespace {}
539
540TYPED_TEST(HttpFetcherTest, PauseTest) {
Andrew de los Reyes9bbd1872010-07-16 14:52:29 -0700541 GMainLoop* loop = g_main_loop_new(g_main_context_default(), FALSE);
rspangler@google.com49fdf182009-10-10 00:57:34 +0000542 {
543 PausingHttpFetcherTestDelegate delegate;
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800544 scoped_ptr<HttpFetcher> fetcher(this->test_.NewLargeFetcher());
rspangler@google.com49fdf182009-10-10 00:57:34 +0000545 delegate.paused_ = false;
546 delegate.loop_ = loop;
547 delegate.fetcher_ = fetcher.get();
548 fetcher->set_delegate(&delegate);
549
Jay Srinivasan43488792012-06-19 00:25:31 -0700550 MockConnectionManager* mock_cm = dynamic_cast<MockConnectionManager*>(
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800551 fetcher->GetSystemState()->connection_manager());
Jay Srinivasan43488792012-06-19 00:25:31 -0700552 EXPECT_CALL(*mock_cm, GetConnectionType(_,_))
553 .WillRepeatedly(DoAll(SetArgumentPointee<1>(kNetCellular), Return(true)));
554 EXPECT_CALL(*mock_cm, IsUpdateAllowedOver(kNetCellular))
555 .WillRepeatedly(Return(true));
556 EXPECT_CALL(*mock_cm, StringForConnectionType(kNetCellular))
557 .WillRepeatedly(Return(flimflam::kTypeCellular));
558
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800559 scoped_ptr<HttpServer> server(this->test_.CreateServer());
560 ASSERT_TRUE(server->started_);
Andrew de los Reyesf3ed8e72011-02-16 10:35:46 -0800561
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800562 guint callback_id = g_timeout_add(kHttpResponseInternalServerError,
563 UnpausingTimeoutCallback, &delegate);
564 fetcher->BeginTransfer(this->test_.BigUrl());
rspangler@google.com49fdf182009-10-10 00:57:34 +0000565
566 g_main_loop_run(loop);
Andrew de los Reyesf3ed8e72011-02-16 10:35:46 -0800567 g_source_remove(callback_id);
rspangler@google.com49fdf182009-10-10 00:57:34 +0000568 }
569 g_main_loop_unref(loop);
570}
571
572namespace {
573class AbortingHttpFetcherTestDelegate : public HttpFetcherDelegate {
574 public:
575 virtual void ReceivedBytes(HttpFetcher* fetcher,
576 const char* bytes, int length) {}
577 virtual void TransferComplete(HttpFetcher* fetcher, bool successful) {
Darin Petkov9ce452b2010-11-17 14:33:28 -0800578 ADD_FAILURE(); // We should never get here
rspangler@google.com49fdf182009-10-10 00:57:34 +0000579 g_main_loop_quit(loop_);
580 }
Darin Petkov9ce452b2010-11-17 14:33:28 -0800581 virtual void TransferTerminated(HttpFetcher* fetcher) {
582 EXPECT_EQ(fetcher, fetcher_.get());
583 EXPECT_FALSE(once_);
584 EXPECT_TRUE(callback_once_);
585 callback_once_ = false;
586 // |fetcher| can be destroyed during this callback.
587 fetcher_.reset(NULL);
Andrew de los Reyes819fef22010-12-17 11:33:58 -0800588 }
rspangler@google.com49fdf182009-10-10 00:57:34 +0000589 void TerminateTransfer() {
590 CHECK(once_);
591 once_ = false;
592 fetcher_->TerminateTransfer();
593 }
594 void EndLoop() {
595 g_main_loop_quit(loop_);
596 }
597 bool once_;
Darin Petkov9ce452b2010-11-17 14:33:28 -0800598 bool callback_once_;
599 scoped_ptr<HttpFetcher> fetcher_;
rspangler@google.com49fdf182009-10-10 00:57:34 +0000600 GMainLoop* loop_;
601};
602
603gboolean AbortingTimeoutCallback(gpointer data) {
604 AbortingHttpFetcherTestDelegate *delegate =
605 reinterpret_cast<AbortingHttpFetcherTestDelegate*>(data);
606 if (delegate->once_) {
607 delegate->TerminateTransfer();
608 return TRUE;
609 } else {
610 delegate->EndLoop();
611 return FALSE;
612 }
613}
614} // namespace {}
615
616TYPED_TEST(HttpFetcherTest, AbortTest) {
Andrew de los Reyes9bbd1872010-07-16 14:52:29 -0700617 GMainLoop* loop = g_main_loop_new(g_main_context_default(), FALSE);
rspangler@google.com49fdf182009-10-10 00:57:34 +0000618 {
619 AbortingHttpFetcherTestDelegate delegate;
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800620 delegate.fetcher_.reset(this->test_.NewLargeFetcher());
rspangler@google.com49fdf182009-10-10 00:57:34 +0000621 delegate.once_ = true;
Darin Petkov9ce452b2010-11-17 14:33:28 -0800622 delegate.callback_once_ = true;
rspangler@google.com49fdf182009-10-10 00:57:34 +0000623 delegate.loop_ = loop;
Darin Petkov9ce452b2010-11-17 14:33:28 -0800624 delegate.fetcher_->set_delegate(&delegate);
rspangler@google.com49fdf182009-10-10 00:57:34 +0000625
Jay Srinivasan43488792012-06-19 00:25:31 -0700626 MockConnectionManager* mock_cm = dynamic_cast<MockConnectionManager*>(
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800627 delegate.fetcher_->GetSystemState()->connection_manager());
Jay Srinivasan43488792012-06-19 00:25:31 -0700628 EXPECT_CALL(*mock_cm, GetConnectionType(_,_))
629 .WillRepeatedly(DoAll(SetArgumentPointee<1>(kNetWifi), Return(true)));
630 EXPECT_CALL(*mock_cm, IsUpdateAllowedOver(kNetWifi))
631 .WillRepeatedly(Return(true));
632 EXPECT_CALL(*mock_cm, StringForConnectionType(kNetWifi))
633 .WillRepeatedly(Return(flimflam::kTypeWifi));
634
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800635 scoped_ptr<HttpServer> server(this->test_.CreateServer());
636 this->test_.IgnoreServerAborting(server.get());
637 ASSERT_TRUE(server->started_);
638
rspangler@google.com49fdf182009-10-10 00:57:34 +0000639 GSource* timeout_source_;
640 timeout_source_ = g_timeout_source_new(0); // ms
641 g_source_set_callback(timeout_source_, AbortingTimeoutCallback, &delegate,
642 NULL);
643 g_source_attach(timeout_source_, NULL);
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800644 delegate.fetcher_->BeginTransfer(this->test_.BigUrl());
rspangler@google.com49fdf182009-10-10 00:57:34 +0000645
646 g_main_loop_run(loop);
Darin Petkov9ce452b2010-11-17 14:33:28 -0800647 CHECK(!delegate.once_);
648 CHECK(!delegate.callback_once_);
rspangler@google.com49fdf182009-10-10 00:57:34 +0000649 g_source_destroy(timeout_source_);
650 }
651 g_main_loop_unref(loop);
652}
653
adlr@google.comc98a7ed2009-12-04 18:54:03 +0000654namespace {
655class FlakyHttpFetcherTestDelegate : public HttpFetcherDelegate {
656 public:
657 virtual void ReceivedBytes(HttpFetcher* fetcher,
658 const char* bytes, int length) {
659 data.append(bytes, length);
660 }
661 virtual void TransferComplete(HttpFetcher* fetcher, bool successful) {
Andrew de los Reyesfb4ad7d2010-07-19 10:43:46 -0700662 EXPECT_TRUE(successful);
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800663 EXPECT_EQ(kHttpResponsePartialContent, fetcher->http_response_code());
adlr@google.comc98a7ed2009-12-04 18:54:03 +0000664 g_main_loop_quit(loop_);
665 }
Darin Petkov9ce452b2010-11-17 14:33:28 -0800666 virtual void TransferTerminated(HttpFetcher* fetcher) {
667 ADD_FAILURE();
668 }
adlr@google.comc98a7ed2009-12-04 18:54:03 +0000669 string data;
670 GMainLoop* loop_;
671};
672} // namespace {}
673
674TYPED_TEST(HttpFetcherTest, FlakyTest) {
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800675 if (this->test_.IsMock())
adlr@google.comc98a7ed2009-12-04 18:54:03 +0000676 return;
Andrew de los Reyes9bbd1872010-07-16 14:52:29 -0700677 GMainLoop* loop = g_main_loop_new(g_main_context_default(), FALSE);
adlr@google.comc98a7ed2009-12-04 18:54:03 +0000678 {
679 FlakyHttpFetcherTestDelegate delegate;
680 delegate.loop_ = loop;
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800681 scoped_ptr<HttpFetcher> fetcher(this->test_.NewSmallFetcher());
adlr@google.comc98a7ed2009-12-04 18:54:03 +0000682 fetcher->set_delegate(&delegate);
683
Jay Srinivasan43488792012-06-19 00:25:31 -0700684 MockConnectionManager* mock_cm = dynamic_cast<MockConnectionManager*>(
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800685 fetcher->GetSystemState()->connection_manager());
Jay Srinivasan43488792012-06-19 00:25:31 -0700686 EXPECT_CALL(*mock_cm, GetConnectionType(_,_))
687 .WillRepeatedly(DoAll(SetArgumentPointee<1>(kNetWifi), Return(true)));
688 EXPECT_CALL(*mock_cm, IsUpdateAllowedOver(kNetWifi))
689 .WillRepeatedly(Return(true));
690 EXPECT_CALL(*mock_cm, StringForConnectionType(kNetWifi))
691 .WillRepeatedly(Return(flimflam::kTypeWifi));
692
693
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800694 scoped_ptr<HttpServer> server(this->test_.CreateServer());
695 ASSERT_TRUE(server->started_);
adlr@google.comc98a7ed2009-12-04 18:54:03 +0000696
697 StartTransferArgs start_xfer_args = {
698 fetcher.get(),
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800699 LocalServerUrlForPath(StringPrintf("/flaky/%d/%d/%d/%d", kBigLength,
700 kFlakyTruncateLength,
701 kFlakySleepEvery,
702 kFlakySleepSecs))
adlr@google.comc98a7ed2009-12-04 18:54:03 +0000703 };
704
705 g_timeout_add(0, StartTransfer, &start_xfer_args);
706 g_main_loop_run(loop);
707
708 // verify the data we get back
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800709 ASSERT_EQ(kBigLength, delegate.data.size());
710 for (int i = 0; i < kBigLength; i += 10) {
adlr@google.comc98a7ed2009-12-04 18:54:03 +0000711 // Assert so that we don't flood the screen w/ EXPECT errors on failure.
712 ASSERT_EQ(delegate.data.substr(i, 10), "abcdefghij");
713 }
714 }
715 g_main_loop_unref(loop);
716}
717
Andrew de los Reyes9bbd1872010-07-16 14:52:29 -0700718namespace {
719class FailureHttpFetcherTestDelegate : public HttpFetcherDelegate {
720 public:
Jay Srinivasan135a58b2012-07-13 12:46:49 -0700721 FailureHttpFetcherTestDelegate(PythonHttpServer* server)
722 : loop_(NULL),
723 server_(server) {}
724
725 virtual ~FailureHttpFetcherTestDelegate() {
726 if (server_) {
727 LOG(INFO) << "Stopping server in destructor";
728 delete server_;
729 LOG(INFO) << "server stopped";
730 }
731 }
732
Andrew de los Reyes9bbd1872010-07-16 14:52:29 -0700733 virtual void ReceivedBytes(HttpFetcher* fetcher,
734 const char* bytes, int length) {
735 if (server_) {
Jay Srinivasan135a58b2012-07-13 12:46:49 -0700736 LOG(INFO) << "Stopping server in ReceivedBytes";
Andrew de los Reyes9bbd1872010-07-16 14:52:29 -0700737 delete server_;
738 LOG(INFO) << "server stopped";
739 server_ = NULL;
740 }
741 }
742 virtual void TransferComplete(HttpFetcher* fetcher, bool successful) {
743 EXPECT_FALSE(successful);
Darin Petkovcb466212010-08-26 09:40:11 -0700744 EXPECT_EQ(0, fetcher->http_response_code());
Andrew de los Reyes9bbd1872010-07-16 14:52:29 -0700745 g_main_loop_quit(loop_);
746 }
Darin Petkov9ce452b2010-11-17 14:33:28 -0800747 virtual void TransferTerminated(HttpFetcher* fetcher) {
748 ADD_FAILURE();
749 }
Andrew de los Reyes9bbd1872010-07-16 14:52:29 -0700750 GMainLoop* loop_;
751 PythonHttpServer* server_;
752};
753} // namespace {}
754
755
756TYPED_TEST(HttpFetcherTest, FailureTest) {
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800757 if (this->test_.IsMock())
Andrew de los Reyes9bbd1872010-07-16 14:52:29 -0700758 return;
759 GMainLoop* loop = g_main_loop_new(g_main_context_default(), FALSE);
760 {
Jay Srinivasan135a58b2012-07-13 12:46:49 -0700761 FailureHttpFetcherTestDelegate delegate(NULL);
Andrew de los Reyes9bbd1872010-07-16 14:52:29 -0700762 delegate.loop_ = loop;
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800763 scoped_ptr<HttpFetcher> fetcher(this->test_.NewSmallFetcher());
Andrew de los Reyes9bbd1872010-07-16 14:52:29 -0700764 fetcher->set_delegate(&delegate);
765
Jay Srinivasan43488792012-06-19 00:25:31 -0700766 MockConnectionManager* mock_cm = dynamic_cast<MockConnectionManager*>(
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800767 fetcher->GetSystemState()->connection_manager());
Jay Srinivasan43488792012-06-19 00:25:31 -0700768 EXPECT_CALL(*mock_cm, GetConnectionType(_,_))
769 .WillRepeatedly(DoAll(SetArgumentPointee<1>(kNetEthernet), Return(true)));
770 EXPECT_CALL(*mock_cm, IsUpdateAllowedOver(kNetEthernet))
771 .WillRepeatedly(Return(true));
772 EXPECT_CALL(*mock_cm, StringForConnectionType(kNetEthernet))
773 .WillRepeatedly(Return(flimflam::kTypeEthernet));
774
775
Andrew de los Reyes9bbd1872010-07-16 14:52:29 -0700776 StartTransferArgs start_xfer_args = {
777 fetcher.get(),
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800778 LocalServerUrlForPath(this->test_.SmallUrl())
Andrew de los Reyes9bbd1872010-07-16 14:52:29 -0700779 };
780
781 g_timeout_add(0, StartTransfer, &start_xfer_args);
782 g_main_loop_run(loop);
783
784 // Exiting and testing happens in the delegate
785 }
786 g_main_loop_unref(loop);
787}
788
789TYPED_TEST(HttpFetcherTest, ServerDiesTest) {
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800790 if (this->test_.IsMock())
Andrew de los Reyes9bbd1872010-07-16 14:52:29 -0700791 return;
792 GMainLoop* loop = g_main_loop_new(g_main_context_default(), FALSE);
793 {
Jay Srinivasan135a58b2012-07-13 12:46:49 -0700794 FailureHttpFetcherTestDelegate delegate(new PythonHttpServer);
Andrew de los Reyes9bbd1872010-07-16 14:52:29 -0700795 delegate.loop_ = loop;
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800796 scoped_ptr<HttpFetcher> fetcher(this->test_.NewSmallFetcher());
Andrew de los Reyes9bbd1872010-07-16 14:52:29 -0700797 fetcher->set_delegate(&delegate);
798
799 StartTransferArgs start_xfer_args = {
800 fetcher.get(),
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800801 LocalServerUrlForPath(StringPrintf("/flaky/%d/%d/%d/%d", kBigLength,
802 kFlakyTruncateLength,
803 kFlakySleepEvery,
804 kFlakySleepSecs))
Andrew de los Reyes9bbd1872010-07-16 14:52:29 -0700805 };
806
807 g_timeout_add(0, StartTransfer, &start_xfer_args);
808 g_main_loop_run(loop);
809
810 // Exiting and testing happens in the delegate
811 }
812 g_main_loop_unref(loop);
813}
814
Darin Petkov41c2fcf2010-08-25 13:14:48 -0700815namespace {
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800816const HttpResponseCode kRedirectCodes[] = {
817 kHttpResponseMovedPermanently, kHttpResponseFound, kHttpResponseSeeOther,
818 kHttpResponseTempRedirect
819};
Darin Petkov41c2fcf2010-08-25 13:14:48 -0700820
821class RedirectHttpFetcherTestDelegate : public HttpFetcherDelegate {
822 public:
823 RedirectHttpFetcherTestDelegate(bool expected_successful)
824 : expected_successful_(expected_successful) {}
825 virtual void ReceivedBytes(HttpFetcher* fetcher,
826 const char* bytes, int length) {
827 data.append(bytes, length);
828 }
829 virtual void TransferComplete(HttpFetcher* fetcher, bool successful) {
830 EXPECT_EQ(expected_successful_, successful);
Darin Petkovcb466212010-08-26 09:40:11 -0700831 if (expected_successful_)
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800832 EXPECT_EQ(kHttpResponseOk, fetcher->http_response_code());
Darin Petkovcb466212010-08-26 09:40:11 -0700833 else {
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800834 EXPECT_GE(fetcher->http_response_code(), kHttpResponseMovedPermanently);
835 EXPECT_LE(fetcher->http_response_code(), kHttpResponseTempRedirect);
Darin Petkovcb466212010-08-26 09:40:11 -0700836 }
Darin Petkov41c2fcf2010-08-25 13:14:48 -0700837 g_main_loop_quit(loop_);
838 }
Darin Petkov9ce452b2010-11-17 14:33:28 -0800839 virtual void TransferTerminated(HttpFetcher* fetcher) {
840 ADD_FAILURE();
841 }
Darin Petkov41c2fcf2010-08-25 13:14:48 -0700842 bool expected_successful_;
843 string data;
844 GMainLoop* loop_;
845};
846
847// RedirectTest takes ownership of |http_fetcher|.
848void RedirectTest(bool expected_successful,
849 const string& url,
850 HttpFetcher* http_fetcher) {
851 GMainLoop* loop = g_main_loop_new(g_main_context_default(), FALSE);
Jay Srinivasan135a58b2012-07-13 12:46:49 -0700852 {
853 RedirectHttpFetcherTestDelegate delegate(expected_successful);
854 delegate.loop_ = loop;
855 scoped_ptr<HttpFetcher> fetcher(http_fetcher);
856 fetcher->set_delegate(&delegate);
Darin Petkov41c2fcf2010-08-25 13:14:48 -0700857
Jay Srinivasan135a58b2012-07-13 12:46:49 -0700858 MockConnectionManager* mock_cm = dynamic_cast<MockConnectionManager*>(
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800859 fetcher->GetSystemState()->connection_manager());
Jay Srinivasan135a58b2012-07-13 12:46:49 -0700860 EXPECT_CALL(*mock_cm, GetConnectionType(_,_))
861 .WillRepeatedly(DoAll(SetArgumentPointee<1>(kNetEthernet), Return(true)));
862 EXPECT_CALL(*mock_cm, IsUpdateAllowedOver(kNetEthernet))
863 .WillRepeatedly(Return(true));
864 EXPECT_CALL(*mock_cm, StringForConnectionType(kNetEthernet))
865 .WillRepeatedly(Return(flimflam::kTypeEthernet));
Jay Srinivasan43488792012-06-19 00:25:31 -0700866
Jay Srinivasan135a58b2012-07-13 12:46:49 -0700867 StartTransferArgs start_xfer_args =
868 { fetcher.get(), LocalServerUrlForPath(url) };
Darin Petkov41c2fcf2010-08-25 13:14:48 -0700869
Jay Srinivasan135a58b2012-07-13 12:46:49 -0700870 g_timeout_add(0, StartTransfer, &start_xfer_args);
871 g_main_loop_run(loop);
872 if (expected_successful) {
873 // verify the data we get back
874 ASSERT_EQ(kMediumLength, delegate.data.size());
875 for (int i = 0; i < kMediumLength; i += 10) {
876 // Assert so that we don't flood the screen w/ EXPECT errors on failure.
877 ASSERT_EQ(delegate.data.substr(i, 10), "abcdefghij");
878 }
Darin Petkov41c2fcf2010-08-25 13:14:48 -0700879 }
880 }
881 g_main_loop_unref(loop);
882}
883} // namespace {}
884
885TYPED_TEST(HttpFetcherTest, SimpleRedirectTest) {
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800886 if (this->test_.IsMock())
Darin Petkov41c2fcf2010-08-25 13:14:48 -0700887 return;
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800888
889 scoped_ptr<HttpServer> server(this->test_.CreateServer());
890 ASSERT_TRUE(server->started_);
891
Darin Petkov41c2fcf2010-08-25 13:14:48 -0700892 for (size_t c = 0; c < arraysize(kRedirectCodes); ++c) {
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800893 const string url = base::StringPrintf("/redirect/%d/download/%d",
894 kRedirectCodes[c],
895 kMediumLength);
896 RedirectTest(true, url, this->test_.NewLargeFetcher());
Darin Petkov41c2fcf2010-08-25 13:14:48 -0700897 }
898}
899
900TYPED_TEST(HttpFetcherTest, MaxRedirectTest) {
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800901 if (this->test_.IsMock())
Darin Petkov41c2fcf2010-08-25 13:14:48 -0700902 return;
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800903
904 scoped_ptr<HttpServer> server(this->test_.CreateServer());
905 ASSERT_TRUE(server->started_);
906
Darin Petkov41c2fcf2010-08-25 13:14:48 -0700907 string url;
908 for (int r = 0; r < LibcurlHttpFetcher::kMaxRedirects; r++) {
909 url += base::StringPrintf("/redirect/%d",
910 kRedirectCodes[r % arraysize(kRedirectCodes)]);
911 }
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800912 url += base::StringPrintf("/download/%d", kMediumLength);
913 RedirectTest(true, url, this->test_.NewLargeFetcher());
Darin Petkov41c2fcf2010-08-25 13:14:48 -0700914}
915
916TYPED_TEST(HttpFetcherTest, BeyondMaxRedirectTest) {
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800917 if (this->test_.IsMock())
Darin Petkov41c2fcf2010-08-25 13:14:48 -0700918 return;
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800919
920 scoped_ptr<HttpServer> server(this->test_.CreateServer());
921 ASSERT_TRUE(server->started_);
922
Darin Petkov41c2fcf2010-08-25 13:14:48 -0700923 string url;
924 for (int r = 0; r < LibcurlHttpFetcher::kMaxRedirects + 1; r++) {
925 url += base::StringPrintf("/redirect/%d",
926 kRedirectCodes[r % arraysize(kRedirectCodes)]);
927 }
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800928 url += base::StringPrintf("/download/%d", kMediumLength);
929 RedirectTest(false, url, this->test_.NewLargeFetcher());
Darin Petkov41c2fcf2010-08-25 13:14:48 -0700930}
931
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -0700932namespace {
933class MultiHttpFetcherTestDelegate : public HttpFetcherDelegate {
934 public:
935 MultiHttpFetcherTestDelegate(int expected_response_code)
936 : expected_response_code_(expected_response_code) {}
Gilad Arnolde4ad2502011-12-29 17:08:54 -0800937
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -0700938 virtual void ReceivedBytes(HttpFetcher* fetcher,
939 const char* bytes, int length) {
Darin Petkov9ce452b2010-11-17 14:33:28 -0800940 EXPECT_EQ(fetcher, fetcher_.get());
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -0700941 data.append(bytes, length);
942 }
Gilad Arnolde4ad2502011-12-29 17:08:54 -0800943
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -0700944 virtual void TransferComplete(HttpFetcher* fetcher, bool successful) {
Darin Petkov9ce452b2010-11-17 14:33:28 -0800945 EXPECT_EQ(fetcher, fetcher_.get());
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800946 EXPECT_EQ(expected_response_code_ != kHttpResponseUndefined, successful);
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -0700947 if (expected_response_code_ != 0)
948 EXPECT_EQ(expected_response_code_, fetcher->http_response_code());
Darin Petkov9ce452b2010-11-17 14:33:28 -0800949 // Destroy the fetcher (because we're allowed to).
950 fetcher_.reset(NULL);
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -0700951 g_main_loop_quit(loop_);
952 }
Gilad Arnolde4ad2502011-12-29 17:08:54 -0800953
Darin Petkov9ce452b2010-11-17 14:33:28 -0800954 virtual void TransferTerminated(HttpFetcher* fetcher) {
955 ADD_FAILURE();
956 }
Gilad Arnolde4ad2502011-12-29 17:08:54 -0800957
Darin Petkov9ce452b2010-11-17 14:33:28 -0800958 scoped_ptr<HttpFetcher> fetcher_;
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -0700959 int expected_response_code_;
960 string data;
961 GMainLoop* loop_;
962};
963
964void MultiTest(HttpFetcher* fetcher_in,
965 const string& url,
Andrew de los Reyes819fef22010-12-17 11:33:58 -0800966 const vector<pair<off_t, off_t> >& ranges,
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -0700967 const string& expected_prefix,
968 off_t expected_size,
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800969 HttpResponseCode expected_response_code) {
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -0700970 GMainLoop* loop = g_main_loop_new(g_main_context_default(), FALSE);
971 {
972 MultiHttpFetcherTestDelegate delegate(expected_response_code);
973 delegate.loop_ = loop;
Darin Petkov9ce452b2010-11-17 14:33:28 -0800974 delegate.fetcher_.reset(fetcher_in);
Jay Srinivasan43488792012-06-19 00:25:31 -0700975
976 MockConnectionManager* mock_cm = dynamic_cast<MockConnectionManager*>(
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800977 fetcher_in->GetSystemState()->connection_manager());
Jay Srinivasan43488792012-06-19 00:25:31 -0700978 EXPECT_CALL(*mock_cm, GetConnectionType(_,_))
979 .WillRepeatedly(DoAll(SetArgumentPointee<1>(kNetWifi), Return(true)));
980 EXPECT_CALL(*mock_cm, IsUpdateAllowedOver(kNetWifi))
981 .WillRepeatedly(Return(true));
982 EXPECT_CALL(*mock_cm, StringForConnectionType(kNetWifi))
983 .WillRepeatedly(Return(flimflam::kTypeWifi));
984
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800985 MultiRangeHttpFetcher* multi_fetcher =
986 dynamic_cast<MultiRangeHttpFetcher*>(fetcher_in);
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -0700987 ASSERT_TRUE(multi_fetcher);
Andrew de los Reyes819fef22010-12-17 11:33:58 -0800988 multi_fetcher->ClearRanges();
989 for (vector<pair<off_t, off_t> >::const_iterator it = ranges.begin(),
990 e = ranges.end(); it != e; ++it) {
Gilad Arnolde4ad2502011-12-29 17:08:54 -0800991 std::string tmp_str = StringPrintf("%jd+", it->first);
992 if (it->second > 0) {
993 base::StringAppendF(&tmp_str, "%jd", it->second);
994 multi_fetcher->AddRange(it->first, it->second);
995 } else {
996 base::StringAppendF(&tmp_str, "?");
997 multi_fetcher->AddRange(it->first);
998 }
999 LOG(INFO) << "added range: " << tmp_str;
Andrew de los Reyes819fef22010-12-17 11:33:58 -08001000 }
Darin Petkovfc7a0ce2010-10-25 10:38:37 -07001001 multi_fetcher->SetBuildType(false);
Darin Petkov9ce452b2010-11-17 14:33:28 -08001002 multi_fetcher->set_delegate(&delegate);
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -07001003
Darin Petkov9ce452b2010-11-17 14:33:28 -08001004 StartTransferArgs start_xfer_args = {multi_fetcher, url};
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -07001005
1006 g_timeout_add(0, StartTransfer, &start_xfer_args);
1007 g_main_loop_run(loop);
1008
1009 EXPECT_EQ(expected_size, delegate.data.size());
1010 EXPECT_EQ(expected_prefix,
1011 string(delegate.data.data(), expected_prefix.size()));
1012 }
1013 g_main_loop_unref(loop);
1014}
1015} // namespace {}
1016
Darin Petkov9ce452b2010-11-17 14:33:28 -08001017TYPED_TEST(HttpFetcherTest, MultiHttpFetcherSimpleTest) {
Gilad Arnold9bedeb52011-11-17 16:19:57 -08001018 if (!this->test_.IsMulti())
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -07001019 return;
Gilad Arnold9bedeb52011-11-17 16:19:57 -08001020
1021 scoped_ptr<HttpServer> server(this->test_.CreateServer());
1022 ASSERT_TRUE(server->started_);
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -07001023
Andrew de los Reyes819fef22010-12-17 11:33:58 -08001024 vector<pair<off_t, off_t> > ranges;
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -07001025 ranges.push_back(make_pair(0, 25));
Gilad Arnolde4ad2502011-12-29 17:08:54 -08001026 ranges.push_back(make_pair(99, 0));
Gilad Arnold9bedeb52011-11-17 16:19:57 -08001027 MultiTest(this->test_.NewLargeFetcher(),
1028 this->test_.BigUrl(),
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -07001029 ranges,
1030 "abcdefghijabcdefghijabcdejabcdefghijabcdef",
Gilad Arnold9bedeb52011-11-17 16:19:57 -08001031 kBigLength - (99 - 25),
1032 kHttpResponsePartialContent);
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -07001033}
1034
1035TYPED_TEST(HttpFetcherTest, MultiHttpFetcherLengthLimitTest) {
Gilad Arnold9bedeb52011-11-17 16:19:57 -08001036 if (!this->test_.IsMulti())
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -07001037 return;
Gilad Arnold9bedeb52011-11-17 16:19:57 -08001038
1039 scoped_ptr<HttpServer> server(this->test_.CreateServer());
1040 ASSERT_TRUE(server->started_);
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -07001041
Andrew de los Reyes819fef22010-12-17 11:33:58 -08001042 vector<pair<off_t, off_t> > ranges;
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -07001043 ranges.push_back(make_pair(0, 24));
Gilad Arnold9bedeb52011-11-17 16:19:57 -08001044 MultiTest(this->test_.NewLargeFetcher(),
1045 this->test_.BigUrl(),
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -07001046 ranges,
1047 "abcdefghijabcdefghijabcd",
1048 24,
Gilad Arnolde4ad2502011-12-29 17:08:54 -08001049 kHttpResponsePartialContent);
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -07001050}
1051
1052TYPED_TEST(HttpFetcherTest, MultiHttpFetcherMultiEndTest) {
Gilad Arnold9bedeb52011-11-17 16:19:57 -08001053 if (!this->test_.IsMulti())
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -07001054 return;
Gilad Arnold9bedeb52011-11-17 16:19:57 -08001055
1056 scoped_ptr<HttpServer> server(this->test_.CreateServer());
1057 ASSERT_TRUE(server->started_);
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -07001058
Andrew de los Reyes819fef22010-12-17 11:33:58 -08001059 vector<pair<off_t, off_t> > ranges;
Gilad Arnolde4ad2502011-12-29 17:08:54 -08001060 ranges.push_back(make_pair(kBigLength - 2, 0));
1061 ranges.push_back(make_pair(kBigLength - 3, 0));
Gilad Arnold9bedeb52011-11-17 16:19:57 -08001062 MultiTest(this->test_.NewLargeFetcher(),
1063 this->test_.BigUrl(),
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -07001064 ranges,
1065 "ijhij",
1066 5,
Gilad Arnold9bedeb52011-11-17 16:19:57 -08001067 kHttpResponsePartialContent);
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -07001068}
1069
1070TYPED_TEST(HttpFetcherTest, MultiHttpFetcherInsufficientTest) {
Gilad Arnold9bedeb52011-11-17 16:19:57 -08001071 if (!this->test_.IsMulti())
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -07001072 return;
Gilad Arnold9bedeb52011-11-17 16:19:57 -08001073
1074 scoped_ptr<HttpServer> server(this->test_.CreateServer());
1075 ASSERT_TRUE(server->started_);
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -07001076
Andrew de los Reyes819fef22010-12-17 11:33:58 -08001077 vector<pair<off_t, off_t> > ranges;
Gilad Arnold9bedeb52011-11-17 16:19:57 -08001078 ranges.push_back(make_pair(kBigLength - 2, 4));
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -07001079 for (int i = 0; i < 2; ++i) {
Andrew de los Reyes819fef22010-12-17 11:33:58 -08001080 LOG(INFO) << "i = " << i;
Gilad Arnold9bedeb52011-11-17 16:19:57 -08001081 MultiTest(this->test_.NewLargeFetcher(),
1082 this->test_.BigUrl(),
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -07001083 ranges,
1084 "ij",
1085 2,
Gilad Arnold9bedeb52011-11-17 16:19:57 -08001086 kHttpResponseUndefined);
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -07001087 ranges.push_back(make_pair(0, 5));
1088 }
1089}
1090
Gilad Arnold9bedeb52011-11-17 16:19:57 -08001091// Issue #18143: when a fetch of a secondary chunk out of a chain, then it
1092// should retry with other proxies listed before giving up.
1093//
1094// (1) successful recovery: The offset fetch will fail twice but succeed with
1095// the third proxy.
1096TYPED_TEST(HttpFetcherTest, MultiHttpFetcherErrorIfOffsetRecoverableTest) {
1097 if (!this->test_.IsMulti())
1098 return;
1099
1100 scoped_ptr<HttpServer> server(this->test_.CreateServer());
1101 ASSERT_TRUE(server->started_);
1102
1103 vector<pair<off_t, off_t> > ranges;
1104 ranges.push_back(make_pair(0, 25));
Gilad Arnolde4ad2502011-12-29 17:08:54 -08001105 ranges.push_back(make_pair(99, 0));
Gilad Arnold9bedeb52011-11-17 16:19:57 -08001106 MultiTest(this->test_.NewLargeFetcher(3),
1107 LocalServerUrlForPath(base::StringPrintf("/error-if-offset/%d/2",
1108 kBigLength)),
1109 ranges,
1110 "abcdefghijabcdefghijabcdejabcdefghijabcdef",
1111 kBigLength - (99 - 25),
1112 kHttpResponsePartialContent);
1113}
1114
1115// (2) unsuccessful recovery: The offset fetch will fail repeatedly. The
1116// fetcher will signal a (failed) completed transfer to the delegate.
1117TYPED_TEST(HttpFetcherTest, MultiHttpFetcherErrorIfOffsetUnrecoverableTest) {
1118 if (!this->test_.IsMulti())
1119 return;
1120
1121 scoped_ptr<HttpServer> server(this->test_.CreateServer());
1122 ASSERT_TRUE(server->started_);
1123
1124 vector<pair<off_t, off_t> > ranges;
1125 ranges.push_back(make_pair(0, 25));
Gilad Arnolde4ad2502011-12-29 17:08:54 -08001126 ranges.push_back(make_pair(99, 0));
Gilad Arnold9bedeb52011-11-17 16:19:57 -08001127 MultiTest(this->test_.NewLargeFetcher(2),
1128 LocalServerUrlForPath(base::StringPrintf("/error-if-offset/%d/3",
1129 kBigLength)),
1130 ranges,
1131 "abcdefghijabcdefghijabcde", // only received the first chunk
1132 25,
1133 kHttpResponseUndefined);
1134}
1135
1136
1137
Andrew de los Reyesd57d1472010-10-21 13:34:08 -07001138namespace {
Darin Petkovfc7a0ce2010-10-25 10:38:37 -07001139class BlockedTransferTestDelegate : public HttpFetcherDelegate {
Andrew de los Reyesd57d1472010-10-21 13:34:08 -07001140 public:
1141 virtual void ReceivedBytes(HttpFetcher* fetcher,
1142 const char* bytes, int length) {
1143 ADD_FAILURE();
1144 }
1145 virtual void TransferComplete(HttpFetcher* fetcher, bool successful) {
1146 EXPECT_FALSE(successful);
1147 g_main_loop_quit(loop_);
1148 }
Darin Petkov9ce452b2010-11-17 14:33:28 -08001149 virtual void TransferTerminated(HttpFetcher* fetcher) {
1150 ADD_FAILURE();
1151 }
Andrew de los Reyesd57d1472010-10-21 13:34:08 -07001152 GMainLoop* loop_;
1153};
1154
1155} // namespace
1156
Darin Petkovfc7a0ce2010-10-25 10:38:37 -07001157TYPED_TEST(HttpFetcherTest, BlockedTransferTest) {
Gilad Arnold9bedeb52011-11-17 16:19:57 -08001158 if (this->test_.IsMock() || this->test_.IsMulti())
Andrew de los Reyesd57d1472010-10-21 13:34:08 -07001159 return;
Andrew de los Reyesd57d1472010-10-21 13:34:08 -07001160
Darin Petkovfc7a0ce2010-10-25 10:38:37 -07001161 for (int i = 0; i < 2; i++) {
Gilad Arnold9bedeb52011-11-17 16:19:57 -08001162 scoped_ptr<HttpServer> server(this->test_.CreateServer());
1163 ASSERT_TRUE(server->started_);
Andrew de los Reyesd57d1472010-10-21 13:34:08 -07001164
Darin Petkovfc7a0ce2010-10-25 10:38:37 -07001165 GMainLoop* loop = g_main_loop_new(g_main_context_default(), FALSE);
Jay Srinivasan135a58b2012-07-13 12:46:49 -07001166 {
1167 BlockedTransferTestDelegate delegate;
1168 delegate.loop_ = loop;
Andrew de los Reyesd57d1472010-10-21 13:34:08 -07001169
Jay Srinivasan135a58b2012-07-13 12:46:49 -07001170 bool is_allowed = (i != 0);
1171 scoped_ptr<HttpFetcher> fetcher(this->test_.NewLargeFetcher());
1172 MockConnectionManager* mock_cm = dynamic_cast<MockConnectionManager*>(
Jay Srinivasan6f6ea002012-12-14 11:26:28 -08001173 fetcher->GetSystemState()->connection_manager());
Jay Srinivasan135a58b2012-07-13 12:46:49 -07001174 EXPECT_CALL(*mock_cm, GetConnectionType(_,_))
1175 .WillRepeatedly(DoAll(SetArgumentPointee<1>(kNetWifi), Return(true)));
1176 EXPECT_CALL(*mock_cm, IsUpdateAllowedOver(kNetWifi))
1177 .WillRepeatedly(Return(is_allowed));
1178 EXPECT_CALL(*mock_cm, StringForConnectionType(kNetWifi))
1179 .WillRepeatedly(Return(flimflam::kTypeWifi));
Jay Srinivasan43488792012-06-19 00:25:31 -07001180
Jay Srinivasan135a58b2012-07-13 12:46:49 -07001181 bool is_official_build = (i == 1);
1182 LOG(INFO) << "is_update_allowed_over_connection: " << is_allowed;
1183 LOG(INFO) << "is_official_build: " << is_official_build;
1184 fetcher->SetBuildType(is_official_build);
1185 fetcher->set_delegate(&delegate);
Darin Petkovfc7a0ce2010-10-25 10:38:37 -07001186
Jay Srinivasan135a58b2012-07-13 12:46:49 -07001187 StartTransferArgs start_xfer_args =
1188 { fetcher.get(), LocalServerUrlForPath(this->test_.SmallUrl()) };
Darin Petkovfc7a0ce2010-10-25 10:38:37 -07001189
Jay Srinivasan135a58b2012-07-13 12:46:49 -07001190 g_timeout_add(0, StartTransfer, &start_xfer_args);
1191 g_main_loop_run(loop);
1192 }
Darin Petkovfc7a0ce2010-10-25 10:38:37 -07001193 g_main_loop_unref(loop);
1194 }
Andrew de los Reyesd57d1472010-10-21 13:34:08 -07001195}
1196
rspangler@google.com49fdf182009-10-10 00:57:34 +00001197} // namespace chromeos_update_engine