blob: e6204d3b7a01ec17c1ec27eddbf928211352472b [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"
21#include "update_engine/http_fetcher_unittest.h"
rspangler@google.com49fdf182009-10-10 00:57:34 +000022#include "update_engine/libcurl_http_fetcher.h"
Jay Srinivasan43488792012-06-19 00:25:31 -070023#include "update_engine/mock_connection_manager.h"
rspangler@google.com49fdf182009-10-10 00:57:34 +000024#include "update_engine/mock_http_fetcher.h"
Jay Srinivasan08fce042012-06-07 16:31:01 -070025#include "update_engine/mock_system_state.h"
Andrew de los Reyes819fef22010-12-17 11:33:58 -080026#include "update_engine/multi_range_http_fetcher.h"
Andrew de los Reyes45168102010-11-22 11:13:50 -080027#include "update_engine/proxy_resolver.h"
Jay Srinivasan08fce042012-06-07 16:31:01 -070028#include "update_engine/utils.h"
rspangler@google.com49fdf182009-10-10 00:57:34 +000029
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -070030using std::make_pair;
Andrew de los Reyes819fef22010-12-17 11:33:58 -080031using std::pair;
adlr@google.comc98a7ed2009-12-04 18:54:03 +000032using std::string;
33using std::vector;
34
Gilad Arnold8e3f1262013-01-08 14:59:54 -080035using base::TimeDelta;
Jay Srinivasan43488792012-06-19 00:25:31 -070036using testing::_;
37using testing::SetArgumentPointee;
38using testing::DoAll;
39using testing::Return;
40
Gilad Arnold9bedeb52011-11-17 16:19:57 -080041namespace {
42
43const int kBigLength = 100000;
44const int kMediumLength = 1000;
Gilad Arnold34bf1ee2012-02-09 16:16:02 -080045const int kFlakyTruncateLength = 29000;
46const int kFlakySleepEvery = 3;
Gilad Arnold9bedeb52011-11-17 16:19:57 -080047const int kFlakySleepSecs = 10;
48
49} // namespace
50
rspangler@google.com49fdf182009-10-10 00:57:34 +000051namespace chromeos_update_engine {
52
Gilad Arnold9bedeb52011-11-17 16:19:57 -080053static const char *kUnusedUrl = "unused://unused";
54
55static inline string LocalServerUrlForPath(const string& path) {
Jay Srinivasan43488792012-06-19 00:25:31 -070056 return base::StringPrintf("http://127.0.0.1:%d%s", kServerPort, path.c_str());
rspangler@google.com49fdf182009-10-10 00:57:34 +000057}
58
Gilad Arnold9bedeb52011-11-17 16:19:57 -080059//
60// Class hierarchy for HTTP server implementations.
61//
62
63class HttpServer {
rspangler@google.com49fdf182009-10-10 00:57:34 +000064 public:
Gilad Arnold9bedeb52011-11-17 16:19:57 -080065 // This makes it an abstract class (dirty but works).
66 virtual ~HttpServer() = 0;
67
rspangler@google.com49fdf182009-10-10 00:57:34 +000068 bool started_;
69};
70
Gilad Arnold9bedeb52011-11-17 16:19:57 -080071HttpServer::~HttpServer() {}
rspangler@google.com49fdf182009-10-10 00:57:34 +000072
Gilad Arnold9bedeb52011-11-17 16:19:57 -080073
74class NullHttpServer : public HttpServer {
rspangler@google.com49fdf182009-10-10 00:57:34 +000075 public:
Gilad Arnold9bedeb52011-11-17 16:19:57 -080076 NullHttpServer() {
77 started_ = true;
rspangler@google.com49fdf182009-10-10 00:57:34 +000078 }
rspangler@google.com49fdf182009-10-10 00:57:34 +000079};
80
Gilad Arnold9bedeb52011-11-17 16:19:57 -080081
82class PythonHttpServer : public HttpServer {
rspangler@google.com49fdf182009-10-10 00:57:34 +000083 public:
84 PythonHttpServer() {
adlr@google.comc98a7ed2009-12-04 18:54:03 +000085 char *argv[2] = {strdup("./test_http_server"), NULL};
rspangler@google.com49fdf182009-10-10 00:57:34 +000086 GError *err;
87 started_ = false;
Andrew de los Reyes08c4e272010-04-15 14:02:17 -070088 validate_quit_ = true;
rspangler@google.com49fdf182009-10-10 00:57:34 +000089 if (!g_spawn_async(NULL,
90 argv,
91 NULL,
92 G_SPAWN_DO_NOT_REAP_CHILD,
93 NULL,
94 NULL,
95 &pid_,
96 &err)) {
Jay Srinivasan135a58b2012-07-13 12:46:49 -070097 LOG(INFO) << "unable to spawn http server process";
rspangler@google.com49fdf182009-10-10 00:57:34 +000098 return;
99 }
Jay Srinivasan135a58b2012-07-13 12:46:49 -0700100 LOG(INFO) << "started http server with pid " << pid_;
rspangler@google.com49fdf182009-10-10 00:57:34 +0000101 int rc = 1;
Gilad Arnold8e3f1262013-01-08 14:59:54 -0800102 const TimeDelta kMaxSleep = TimeDelta::FromMinutes(60);
103 TimeDelta timeout = TimeDelta::FromMilliseconds(15);
Andrew de los Reyes3270f742010-07-15 22:28:14 -0700104 started_ = true;
Jay Srinivasan135a58b2012-07-13 12:46:49 -0700105 while (rc && timeout < kMaxSleep) {
106 // Wait before the first attempt also as it takes a while for the
107 // test_http_server to be ready.
Gilad Arnold8e3f1262013-01-08 14:59:54 -0800108 LOG(INFO) << "waiting for " << utils::FormatTimeDelta(timeout);
109 g_usleep(timeout.InMicroseconds());
Jay Srinivasan135a58b2012-07-13 12:46:49 -0700110 timeout *= 2;
111
Andrew de los Reyes3270f742010-07-15 22:28:14 -0700112 LOG(INFO) << "running wget to start";
Jay Srinivasan135a58b2012-07-13 12:46:49 -0700113 // rc should be 0 if we're able to successfully talk to the server.
rspangler@google.com49fdf182009-10-10 00:57:34 +0000114 rc = system((string("wget --output-document=/dev/null ") +
115 LocalServerUrlForPath("/test")).c_str());
Jay Srinivasan135a58b2012-07-13 12:46:49 -0700116 LOG(INFO) << "done running wget to start, rc = " << rc;
rspangler@google.com49fdf182009-10-10 00:57:34 +0000117 }
Jay Srinivasan135a58b2012-07-13 12:46:49 -0700118
119 if (rc) {
120 LOG(ERROR) << "Http server is not responding to wget.";
121 // TODO(jaysri): Currently we're overloading two things in
122 // started_ flag. One is that the process is running and other
123 // is that the process is responsive. We should separate these
124 // two so that we can do cleanup appropriately in each case.
125 started_ = false;
126 }
127
rspangler@google.com49fdf182009-10-10 00:57:34 +0000128 free(argv[0]);
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -0700129 LOG(INFO) << "gdb attach now!";
rspangler@google.com49fdf182009-10-10 00:57:34 +0000130 }
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800131
rspangler@google.com49fdf182009-10-10 00:57:34 +0000132 ~PythonHttpServer() {
Jay Srinivasan135a58b2012-07-13 12:46:49 -0700133 if (!started_) {
134 LOG(INFO) << "not waiting for http server with pid " << pid_
135 << " to terminate, as it's not responding.";
136 // TODO(jaysri): Kill the process if it's really running but
137 // wgets or failing for some reason. Or if it's not running,
138 // add code to get rid of the defunct process.
rspangler@google.com49fdf182009-10-10 00:57:34 +0000139 return;
Jay Srinivasan135a58b2012-07-13 12:46:49 -0700140 }
141
rspangler@google.com49fdf182009-10-10 00:57:34 +0000142 // request that the server exit itself
Andrew de los Reyes3270f742010-07-15 22:28:14 -0700143 LOG(INFO) << "running wget to exit";
Andrew de los Reyes08c4e272010-04-15 14:02:17 -0700144 int rc = system((string("wget -t 1 --output-document=/dev/null ") +
Andrew de los Reyes9bbd1872010-07-16 14:52:29 -0700145 LocalServerUrlForPath("/quitquitquit")).c_str());
Andrew de los Reyes3270f742010-07-15 22:28:14 -0700146 LOG(INFO) << "done running wget to exit";
Andrew de los Reyes08c4e272010-04-15 14:02:17 -0700147 if (validate_quit_)
148 EXPECT_EQ(0, rc);
Jay Srinivasan135a58b2012-07-13 12:46:49 -0700149 LOG(INFO) << "waiting for http server with pid " << pid_ << " to terminate";
150 int status;
151 waitpid(pid_, &status, 0);
152 LOG(INFO) << "http server with pid " << pid_
153 << " terminated with status " << status;
rspangler@google.com49fdf182009-10-10 00:57:34 +0000154 }
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800155
rspangler@google.com49fdf182009-10-10 00:57:34 +0000156 GPid pid_;
Andrew de los Reyes08c4e272010-04-15 14:02:17 -0700157 bool validate_quit_;
rspangler@google.com49fdf182009-10-10 00:57:34 +0000158};
159
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800160//
161// Class hierarchy for HTTP fetcher test wrappers.
162//
163
164class AnyHttpFetcherTest {
rspangler@google.com49fdf182009-10-10 00:57:34 +0000165 public:
Jay Srinivasan43488792012-06-19 00:25:31 -0700166 AnyHttpFetcherTest()
167 : mock_connection_manager_(&mock_system_state_) {
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800168 mock_system_state_.set_connection_manager(&mock_connection_manager_);
Jay Srinivasan43488792012-06-19 00:25:31 -0700169 }
170
171 virtual HttpFetcher* NewLargeFetcher(size_t num_proxies) = 0;
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800172 HttpFetcher* NewLargeFetcher() {
173 return NewLargeFetcher(1);
174 }
175
176 virtual HttpFetcher* NewSmallFetcher(size_t num_proxies) = 0;
177 HttpFetcher* NewSmallFetcher() {
178 return NewSmallFetcher(1);
179 }
180
181 virtual string BigUrl() const { return kUnusedUrl; }
182 virtual string SmallUrl() const { return kUnusedUrl; }
183 virtual string ErrorUrl() const { return kUnusedUrl; }
184
185 virtual bool IsMock() const = 0;
186 virtual bool IsMulti() const = 0;
187
188 virtual void IgnoreServerAborting(HttpServer* server) const {}
189
190 virtual HttpServer *CreateServer() = 0;
191
192 protected:
193 DirectProxyResolver proxy_resolver_;
Jay Srinivasan43488792012-06-19 00:25:31 -0700194 MockSystemState mock_system_state_;
195 MockConnectionManager mock_connection_manager_;
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800196};
197
198class MockHttpFetcherTest : public AnyHttpFetcherTest {
199 public:
200 // Necessary to unhide the definition in the base class.
201 using AnyHttpFetcherTest::NewLargeFetcher;
202 virtual HttpFetcher* NewLargeFetcher(size_t num_proxies) {
203 vector<char> big_data(1000000);
204 CHECK(num_proxies > 0);
205 proxy_resolver_.set_num_proxies(num_proxies);
206 return new MockHttpFetcher(
207 big_data.data(),
208 big_data.size(),
209 reinterpret_cast<ProxyResolver*>(&proxy_resolver_));
210 }
211
212 // Necessary to unhide the definition in the base class.
213 using AnyHttpFetcherTest::NewSmallFetcher;
214 virtual HttpFetcher* NewSmallFetcher(size_t num_proxies) {
215 CHECK(num_proxies > 0);
216 proxy_resolver_.set_num_proxies(num_proxies);
217 return new MockHttpFetcher(
218 "x",
219 1,
220 reinterpret_cast<ProxyResolver*>(&proxy_resolver_));
221 }
222
223 virtual bool IsMock() const { return true; }
224 virtual bool IsMulti() const { return false; }
225
226 virtual HttpServer *CreateServer() {
227 return new NullHttpServer;
228 }
229};
230
231class LibcurlHttpFetcherTest : public AnyHttpFetcherTest {
232 public:
233 // Necessary to unhide the definition in the base class.
234 using AnyHttpFetcherTest::NewLargeFetcher;
235 virtual HttpFetcher* NewLargeFetcher(size_t num_proxies) {
236 CHECK(num_proxies > 0);
237 proxy_resolver_.set_num_proxies(num_proxies);
Andrew de los Reyes45168102010-11-22 11:13:50 -0800238 LibcurlHttpFetcher *ret = new
Jay Srinivasan08fce042012-06-07 16:31:01 -0700239 LibcurlHttpFetcher(reinterpret_cast<ProxyResolver*>(&proxy_resolver_),
Gilad Arnold7c04e762012-05-23 10:54:02 -0700240 &mock_system_state_, false);
Darin Petkovb83371f2010-08-17 09:34:49 -0700241 // Speed up test execution.
242 ret->set_idle_seconds(1);
243 ret->set_retry_seconds(1);
Darin Petkovfc7a0ce2010-10-25 10:38:37 -0700244 ret->SetBuildType(false);
rspangler@google.com49fdf182009-10-10 00:57:34 +0000245 return ret;
246 }
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800247
248 // Necessary to unhide the definition in the base class.
249 using AnyHttpFetcherTest::NewSmallFetcher;
250 virtual HttpFetcher* NewSmallFetcher(size_t num_proxies) {
251 return NewLargeFetcher(num_proxies);
rspangler@google.com49fdf182009-10-10 00:57:34 +0000252 }
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800253
254 virtual string BigUrl() const {
255 return LocalServerUrlForPath(base::StringPrintf("/download/%d",
256 kBigLength));
rspangler@google.com49fdf182009-10-10 00:57:34 +0000257 }
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800258 virtual string SmallUrl() const {
rspangler@google.com49fdf182009-10-10 00:57:34 +0000259 return LocalServerUrlForPath("/foo");
260 }
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800261 virtual string ErrorUrl() const {
Gilad Arnold48085ba2011-11-16 09:36:08 -0800262 return LocalServerUrlForPath("/error");
263 }
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800264
265 virtual bool IsMock() const { return false; }
266 virtual bool IsMulti() const { return false; }
267
268 virtual void IgnoreServerAborting(HttpServer* server) const {
Andrew de los Reyes08c4e272010-04-15 14:02:17 -0700269 PythonHttpServer *pyserver = reinterpret_cast<PythonHttpServer*>(server);
270 pyserver->validate_quit_ = false;
271 }
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800272
273 virtual HttpServer *CreateServer() {
274 return new PythonHttpServer;
275 }
rspangler@google.com49fdf182009-10-10 00:57:34 +0000276};
277
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800278class MultiRangeHttpFetcherTest : public LibcurlHttpFetcherTest {
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -0700279 public:
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800280 // Necessary to unhide the definition in the base class.
281 using AnyHttpFetcherTest::NewLargeFetcher;
282 virtual HttpFetcher* NewLargeFetcher(size_t num_proxies) {
283 CHECK(num_proxies > 0);
284 proxy_resolver_.set_num_proxies(num_proxies);
Andrew de los Reyes819fef22010-12-17 11:33:58 -0800285 ProxyResolver* resolver =
286 reinterpret_cast<ProxyResolver*>(&proxy_resolver_);
Gilad Arnold7c04e762012-05-23 10:54:02 -0700287 MultiRangeHttpFetcher *ret =
288 new MultiRangeHttpFetcher(
289 new LibcurlHttpFetcher(resolver, &mock_system_state_, false));
Andrew de los Reyes819fef22010-12-17 11:33:58 -0800290 ret->ClearRanges();
Gilad Arnolde4ad2502011-12-29 17:08:54 -0800291 ret->AddRange(0);
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -0700292 // Speed up test execution.
293 ret->set_idle_seconds(1);
294 ret->set_retry_seconds(1);
Darin Petkovfc7a0ce2010-10-25 10:38:37 -0700295 ret->SetBuildType(false);
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -0700296 return ret;
297 }
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800298
299 // Necessary to unhide the definition in the base class.
300 using AnyHttpFetcherTest::NewSmallFetcher;
301 virtual HttpFetcher* NewSmallFetcher(size_t num_proxies) {
302 return NewLargeFetcher(num_proxies);
303 }
304
305 virtual bool IsMulti() const { return true; }
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -0700306};
307
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800308
309//
310// Infrastructure for type tests of HTTP fetcher.
311// See: http://code.google.com/p/googletest/wiki/AdvancedGuide#Typed_Tests
312//
313
314// Fixture class template. We use an explicit constraint to guarantee that it
315// can only be instantiated with an AnyHttpFetcherTest type, see:
316// http://www2.research.att.com/~bs/bs_faq2.html#constraints
317template <typename T>
318class HttpFetcherTest : public ::testing::Test {
319 public:
320 T test_;
321
322 private:
323 static void TypeConstraint(T *a) {
324 AnyHttpFetcherTest *b = a;
Yunlian Jiang2dac5762013-04-12 09:53:09 -0700325 if (b == 0) // Silence compiler warning of unused variable.
326 *b = a;
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800327 }
328};
329
330// Test case types list.
331typedef ::testing::Types<LibcurlHttpFetcherTest,
332 MockHttpFetcherTest,
333 MultiRangeHttpFetcherTest> HttpFetcherTestTypes;
rspangler@google.com49fdf182009-10-10 00:57:34 +0000334TYPED_TEST_CASE(HttpFetcherTest, HttpFetcherTestTypes);
335
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800336
rspangler@google.com49fdf182009-10-10 00:57:34 +0000337namespace {
338class HttpFetcherTestDelegate : public HttpFetcherDelegate {
adlr@google.comc98a7ed2009-12-04 18:54:03 +0000339 public:
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800340 HttpFetcherTestDelegate() :
Gilad Arnold48085ba2011-11-16 09:36:08 -0800341 is_expect_error_(false), times_transfer_complete_called_(0),
342 times_transfer_terminated_called_(0), times_received_bytes_called_(0) {}
343
rspangler@google.com49fdf182009-10-10 00:57:34 +0000344 virtual void ReceivedBytes(HttpFetcher* fetcher,
345 const char* bytes, int length) {
346 char str[length + 1];
347 memset(str, 0, length + 1);
348 memcpy(str, bytes, length);
Gilad Arnold48085ba2011-11-16 09:36:08 -0800349
350 // Update counters
351 times_received_bytes_called_++;
rspangler@google.com49fdf182009-10-10 00:57:34 +0000352 }
Gilad Arnold48085ba2011-11-16 09:36:08 -0800353
rspangler@google.com49fdf182009-10-10 00:57:34 +0000354 virtual void TransferComplete(HttpFetcher* fetcher, bool successful) {
Gilad Arnold48085ba2011-11-16 09:36:08 -0800355 if (is_expect_error_)
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800356 EXPECT_EQ(kHttpResponseNotFound, fetcher->http_response_code());
Gilad Arnold48085ba2011-11-16 09:36:08 -0800357 else
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800358 EXPECT_EQ(kHttpResponseOk, fetcher->http_response_code());
rspangler@google.com49fdf182009-10-10 00:57:34 +0000359 g_main_loop_quit(loop_);
Gilad Arnold48085ba2011-11-16 09:36:08 -0800360
361 // Update counter
362 times_transfer_complete_called_++;
rspangler@google.com49fdf182009-10-10 00:57:34 +0000363 }
Gilad Arnold48085ba2011-11-16 09:36:08 -0800364
Darin Petkov9ce452b2010-11-17 14:33:28 -0800365 virtual void TransferTerminated(HttpFetcher* fetcher) {
366 ADD_FAILURE();
Gilad Arnold48085ba2011-11-16 09:36:08 -0800367 times_transfer_terminated_called_++;
Darin Petkov9ce452b2010-11-17 14:33:28 -0800368 }
Gilad Arnold48085ba2011-11-16 09:36:08 -0800369
rspangler@google.com49fdf182009-10-10 00:57:34 +0000370 GMainLoop* loop_;
Gilad Arnold48085ba2011-11-16 09:36:08 -0800371
372 // Are we expecting an error response? (default: no)
373 bool is_expect_error_;
374
375 // Counters for callback invocations.
376 int times_transfer_complete_called_;
377 int times_transfer_terminated_called_;
378 int times_received_bytes_called_;
rspangler@google.com49fdf182009-10-10 00:57:34 +0000379};
adlr@google.comc98a7ed2009-12-04 18:54:03 +0000380
381struct StartTransferArgs {
382 HttpFetcher *http_fetcher;
383 string url;
384};
385
386gboolean StartTransfer(gpointer data) {
387 StartTransferArgs *args = reinterpret_cast<StartTransferArgs*>(data);
388 args->http_fetcher->BeginTransfer(args->url);
389 return FALSE;
390}
rspangler@google.com49fdf182009-10-10 00:57:34 +0000391} // namespace {}
392
393TYPED_TEST(HttpFetcherTest, SimpleTest) {
Andrew de los Reyes9bbd1872010-07-16 14:52:29 -0700394 GMainLoop* loop = g_main_loop_new(g_main_context_default(), FALSE);
rspangler@google.com49fdf182009-10-10 00:57:34 +0000395 {
396 HttpFetcherTestDelegate delegate;
397 delegate.loop_ = loop;
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800398 scoped_ptr<HttpFetcher> fetcher(this->test_.NewSmallFetcher());
rspangler@google.com49fdf182009-10-10 00:57:34 +0000399 fetcher->set_delegate(&delegate);
400
Jay Srinivasan43488792012-06-19 00:25:31 -0700401 MockConnectionManager* mock_cm = dynamic_cast<MockConnectionManager*>(
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800402 fetcher->GetSystemState()->connection_manager());
Jay Srinivasan43488792012-06-19 00:25:31 -0700403 EXPECT_CALL(*mock_cm, GetConnectionType(_,_))
404 .WillRepeatedly(DoAll(SetArgumentPointee<1>(kNetWifi), Return(true)));
405 EXPECT_CALL(*mock_cm, IsUpdateAllowedOver(kNetWifi))
406 .WillRepeatedly(Return(true));
407 EXPECT_CALL(*mock_cm, StringForConnectionType(kNetWifi))
408 .WillRepeatedly(Return(flimflam::kTypeWifi));
409
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800410 scoped_ptr<HttpServer> server(this->test_.CreateServer());
411 ASSERT_TRUE(server->started_);
rspangler@google.com49fdf182009-10-10 00:57:34 +0000412
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800413 StartTransferArgs start_xfer_args = {fetcher.get(), this->test_.SmallUrl()};
adlr@google.comc98a7ed2009-12-04 18:54:03 +0000414
415 g_timeout_add(0, StartTransfer, &start_xfer_args);
rspangler@google.com49fdf182009-10-10 00:57:34 +0000416 g_main_loop_run(loop);
417 }
418 g_main_loop_unref(loop);
419}
420
Andrew de los Reyes3270f742010-07-15 22:28:14 -0700421TYPED_TEST(HttpFetcherTest, SimpleBigTest) {
Andrew de los Reyes9bbd1872010-07-16 14:52:29 -0700422 GMainLoop* loop = g_main_loop_new(g_main_context_default(), FALSE);
Andrew de los Reyes3270f742010-07-15 22:28:14 -0700423 {
424 HttpFetcherTestDelegate delegate;
425 delegate.loop_ = loop;
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800426 scoped_ptr<HttpFetcher> fetcher(this->test_.NewLargeFetcher());
Andrew de los Reyes3270f742010-07-15 22:28:14 -0700427 fetcher->set_delegate(&delegate);
428
Jay Srinivasan43488792012-06-19 00:25:31 -0700429 MockConnectionManager* mock_cm = dynamic_cast<MockConnectionManager*>(
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800430 fetcher->GetSystemState()->connection_manager());
Jay Srinivasan43488792012-06-19 00:25:31 -0700431 EXPECT_CALL(*mock_cm, GetConnectionType(_,_))
432 .WillRepeatedly(DoAll(SetArgumentPointee<1>(kNetEthernet), Return(true)));
433 EXPECT_CALL(*mock_cm, IsUpdateAllowedOver(kNetEthernet))
434 .WillRepeatedly(Return(true));
435 EXPECT_CALL(*mock_cm, StringForConnectionType(kNetEthernet))
436 .WillRepeatedly(Return(flimflam::kTypeEthernet));
437
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800438 scoped_ptr<HttpServer> server(this->test_.CreateServer());
439 ASSERT_TRUE(server->started_);
Andrew de los Reyes3270f742010-07-15 22:28:14 -0700440
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800441 StartTransferArgs start_xfer_args = {fetcher.get(), this->test_.BigUrl()};
Andrew de los Reyes3270f742010-07-15 22:28:14 -0700442
443 g_timeout_add(0, StartTransfer, &start_xfer_args);
444 g_main_loop_run(loop);
445 }
446 g_main_loop_unref(loop);
447}
448
Gilad Arnold48085ba2011-11-16 09:36:08 -0800449// Issue #9648: when server returns an error HTTP response, the fetcher needs to
450// terminate transfer prematurely, rather than try to process the error payload.
451TYPED_TEST(HttpFetcherTest, ErrorTest) {
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800452 if (this->test_.IsMock() || this->test_.IsMulti())
Gilad Arnold48085ba2011-11-16 09:36:08 -0800453 return;
454 GMainLoop* loop = g_main_loop_new(g_main_context_default(), FALSE);
455 {
456 HttpFetcherTestDelegate delegate;
457 delegate.loop_ = loop;
458
459 // Delegate should expect an error response.
460 delegate.is_expect_error_ = true;
461
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800462 scoped_ptr<HttpFetcher> fetcher(this->test_.NewSmallFetcher());
Gilad Arnold48085ba2011-11-16 09:36:08 -0800463 fetcher->set_delegate(&delegate);
464
Jay Srinivasan43488792012-06-19 00:25:31 -0700465 MockConnectionManager* mock_cm = dynamic_cast<MockConnectionManager*>(
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800466 fetcher->GetSystemState()->connection_manager());
Jay Srinivasan43488792012-06-19 00:25:31 -0700467 EXPECT_CALL(*mock_cm, GetConnectionType(_,_))
468 .WillRepeatedly(DoAll(SetArgumentPointee<1>(kNetWimax), Return(true)));
469 EXPECT_CALL(*mock_cm, IsUpdateAllowedOver(kNetWimax))
470 .WillRepeatedly(Return(true));
471 EXPECT_CALL(*mock_cm, StringForConnectionType(kNetWimax))
472 .WillRepeatedly(Return(flimflam::kTypeWimax));
473
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800474 scoped_ptr<HttpServer> server(this->test_.CreateServer());
475 ASSERT_TRUE(server->started_);
Gilad Arnold48085ba2011-11-16 09:36:08 -0800476
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800477 StartTransferArgs start_xfer_args = {
478 fetcher.get(),
479 this->test_.ErrorUrl()
480 };
Gilad Arnold48085ba2011-11-16 09:36:08 -0800481
482 g_timeout_add(0, StartTransfer, &start_xfer_args);
483 g_main_loop_run(loop);
484
485 // Make sure that no bytes were received.
486 CHECK_EQ(delegate.times_received_bytes_called_, 0);
Mike Frysinger0f9547d2012-02-16 12:11:37 -0500487 CHECK_EQ(fetcher->GetBytesDownloaded(), static_cast<size_t>(0));
Gilad Arnold48085ba2011-11-16 09:36:08 -0800488
489 // Make sure that transfer completion was signaled once, and no termination
490 // was signaled.
491 CHECK_EQ(delegate.times_transfer_complete_called_, 1);
492 CHECK_EQ(delegate.times_transfer_terminated_called_, 0);
493 }
494 g_main_loop_unref(loop);
495}
496
rspangler@google.com49fdf182009-10-10 00:57:34 +0000497namespace {
498class PausingHttpFetcherTestDelegate : public HttpFetcherDelegate {
499 public:
500 virtual void ReceivedBytes(HttpFetcher* fetcher,
501 const char* bytes, int length) {
502 char str[length + 1];
rspangler@google.com49fdf182009-10-10 00:57:34 +0000503 memset(str, 0, length + 1);
504 memcpy(str, bytes, length);
505 CHECK(!paused_);
506 paused_ = true;
507 fetcher->Pause();
rspangler@google.com49fdf182009-10-10 00:57:34 +0000508 }
509 virtual void TransferComplete(HttpFetcher* fetcher, bool successful) {
510 g_main_loop_quit(loop_);
511 }
Darin Petkov9ce452b2010-11-17 14:33:28 -0800512 virtual void TransferTerminated(HttpFetcher* fetcher) {
513 ADD_FAILURE();
514 }
rspangler@google.com49fdf182009-10-10 00:57:34 +0000515 void Unpause() {
516 CHECK(paused_);
517 paused_ = false;
518 fetcher_->Unpause();
rspangler@google.com49fdf182009-10-10 00:57:34 +0000519 }
520 bool paused_;
521 HttpFetcher* fetcher_;
522 GMainLoop* loop_;
523};
524
525gboolean UnpausingTimeoutCallback(gpointer data) {
526 PausingHttpFetcherTestDelegate *delegate =
527 reinterpret_cast<PausingHttpFetcherTestDelegate*>(data);
528 if (delegate->paused_)
529 delegate->Unpause();
530 return TRUE;
531}
532} // namespace {}
533
534TYPED_TEST(HttpFetcherTest, PauseTest) {
Andrew de los Reyes9bbd1872010-07-16 14:52:29 -0700535 GMainLoop* loop = g_main_loop_new(g_main_context_default(), FALSE);
rspangler@google.com49fdf182009-10-10 00:57:34 +0000536 {
537 PausingHttpFetcherTestDelegate delegate;
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800538 scoped_ptr<HttpFetcher> fetcher(this->test_.NewLargeFetcher());
rspangler@google.com49fdf182009-10-10 00:57:34 +0000539 delegate.paused_ = false;
540 delegate.loop_ = loop;
541 delegate.fetcher_ = fetcher.get();
542 fetcher->set_delegate(&delegate);
543
Jay Srinivasan43488792012-06-19 00:25:31 -0700544 MockConnectionManager* mock_cm = dynamic_cast<MockConnectionManager*>(
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800545 fetcher->GetSystemState()->connection_manager());
Jay Srinivasan43488792012-06-19 00:25:31 -0700546 EXPECT_CALL(*mock_cm, GetConnectionType(_,_))
547 .WillRepeatedly(DoAll(SetArgumentPointee<1>(kNetCellular), Return(true)));
548 EXPECT_CALL(*mock_cm, IsUpdateAllowedOver(kNetCellular))
549 .WillRepeatedly(Return(true));
550 EXPECT_CALL(*mock_cm, StringForConnectionType(kNetCellular))
551 .WillRepeatedly(Return(flimflam::kTypeCellular));
552
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800553 scoped_ptr<HttpServer> server(this->test_.CreateServer());
554 ASSERT_TRUE(server->started_);
Andrew de los Reyesf3ed8e72011-02-16 10:35:46 -0800555
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800556 guint callback_id = g_timeout_add(kHttpResponseInternalServerError,
557 UnpausingTimeoutCallback, &delegate);
558 fetcher->BeginTransfer(this->test_.BigUrl());
rspangler@google.com49fdf182009-10-10 00:57:34 +0000559
560 g_main_loop_run(loop);
Andrew de los Reyesf3ed8e72011-02-16 10:35:46 -0800561 g_source_remove(callback_id);
rspangler@google.com49fdf182009-10-10 00:57:34 +0000562 }
563 g_main_loop_unref(loop);
564}
565
566namespace {
567class AbortingHttpFetcherTestDelegate : public HttpFetcherDelegate {
568 public:
569 virtual void ReceivedBytes(HttpFetcher* fetcher,
570 const char* bytes, int length) {}
571 virtual void TransferComplete(HttpFetcher* fetcher, bool successful) {
Darin Petkov9ce452b2010-11-17 14:33:28 -0800572 ADD_FAILURE(); // We should never get here
rspangler@google.com49fdf182009-10-10 00:57:34 +0000573 g_main_loop_quit(loop_);
574 }
Darin Petkov9ce452b2010-11-17 14:33:28 -0800575 virtual void TransferTerminated(HttpFetcher* fetcher) {
576 EXPECT_EQ(fetcher, fetcher_.get());
577 EXPECT_FALSE(once_);
578 EXPECT_TRUE(callback_once_);
579 callback_once_ = false;
580 // |fetcher| can be destroyed during this callback.
581 fetcher_.reset(NULL);
Andrew de los Reyes819fef22010-12-17 11:33:58 -0800582 }
rspangler@google.com49fdf182009-10-10 00:57:34 +0000583 void TerminateTransfer() {
584 CHECK(once_);
585 once_ = false;
586 fetcher_->TerminateTransfer();
587 }
588 void EndLoop() {
589 g_main_loop_quit(loop_);
590 }
591 bool once_;
Darin Petkov9ce452b2010-11-17 14:33:28 -0800592 bool callback_once_;
593 scoped_ptr<HttpFetcher> fetcher_;
rspangler@google.com49fdf182009-10-10 00:57:34 +0000594 GMainLoop* loop_;
595};
596
597gboolean AbortingTimeoutCallback(gpointer data) {
598 AbortingHttpFetcherTestDelegate *delegate =
599 reinterpret_cast<AbortingHttpFetcherTestDelegate*>(data);
600 if (delegate->once_) {
601 delegate->TerminateTransfer();
602 return TRUE;
603 } else {
604 delegate->EndLoop();
605 return FALSE;
606 }
607}
608} // namespace {}
609
610TYPED_TEST(HttpFetcherTest, AbortTest) {
Andrew de los Reyes9bbd1872010-07-16 14:52:29 -0700611 GMainLoop* loop = g_main_loop_new(g_main_context_default(), FALSE);
rspangler@google.com49fdf182009-10-10 00:57:34 +0000612 {
613 AbortingHttpFetcherTestDelegate delegate;
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800614 delegate.fetcher_.reset(this->test_.NewLargeFetcher());
rspangler@google.com49fdf182009-10-10 00:57:34 +0000615 delegate.once_ = true;
Darin Petkov9ce452b2010-11-17 14:33:28 -0800616 delegate.callback_once_ = true;
rspangler@google.com49fdf182009-10-10 00:57:34 +0000617 delegate.loop_ = loop;
Darin Petkov9ce452b2010-11-17 14:33:28 -0800618 delegate.fetcher_->set_delegate(&delegate);
rspangler@google.com49fdf182009-10-10 00:57:34 +0000619
Jay Srinivasan43488792012-06-19 00:25:31 -0700620 MockConnectionManager* mock_cm = dynamic_cast<MockConnectionManager*>(
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800621 delegate.fetcher_->GetSystemState()->connection_manager());
Jay Srinivasan43488792012-06-19 00:25:31 -0700622 EXPECT_CALL(*mock_cm, GetConnectionType(_,_))
623 .WillRepeatedly(DoAll(SetArgumentPointee<1>(kNetWifi), Return(true)));
624 EXPECT_CALL(*mock_cm, IsUpdateAllowedOver(kNetWifi))
625 .WillRepeatedly(Return(true));
626 EXPECT_CALL(*mock_cm, StringForConnectionType(kNetWifi))
627 .WillRepeatedly(Return(flimflam::kTypeWifi));
628
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800629 scoped_ptr<HttpServer> server(this->test_.CreateServer());
630 this->test_.IgnoreServerAborting(server.get());
631 ASSERT_TRUE(server->started_);
632
rspangler@google.com49fdf182009-10-10 00:57:34 +0000633 GSource* timeout_source_;
634 timeout_source_ = g_timeout_source_new(0); // ms
635 g_source_set_callback(timeout_source_, AbortingTimeoutCallback, &delegate,
636 NULL);
637 g_source_attach(timeout_source_, NULL);
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800638 delegate.fetcher_->BeginTransfer(this->test_.BigUrl());
rspangler@google.com49fdf182009-10-10 00:57:34 +0000639
640 g_main_loop_run(loop);
Darin Petkov9ce452b2010-11-17 14:33:28 -0800641 CHECK(!delegate.once_);
642 CHECK(!delegate.callback_once_);
rspangler@google.com49fdf182009-10-10 00:57:34 +0000643 g_source_destroy(timeout_source_);
644 }
645 g_main_loop_unref(loop);
646}
647
adlr@google.comc98a7ed2009-12-04 18:54:03 +0000648namespace {
649class FlakyHttpFetcherTestDelegate : public HttpFetcherDelegate {
650 public:
651 virtual void ReceivedBytes(HttpFetcher* fetcher,
652 const char* bytes, int length) {
653 data.append(bytes, length);
654 }
655 virtual void TransferComplete(HttpFetcher* fetcher, bool successful) {
Andrew de los Reyesfb4ad7d2010-07-19 10:43:46 -0700656 EXPECT_TRUE(successful);
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800657 EXPECT_EQ(kHttpResponsePartialContent, fetcher->http_response_code());
adlr@google.comc98a7ed2009-12-04 18:54:03 +0000658 g_main_loop_quit(loop_);
659 }
Darin Petkov9ce452b2010-11-17 14:33:28 -0800660 virtual void TransferTerminated(HttpFetcher* fetcher) {
661 ADD_FAILURE();
662 }
adlr@google.comc98a7ed2009-12-04 18:54:03 +0000663 string data;
664 GMainLoop* loop_;
665};
666} // namespace {}
667
668TYPED_TEST(HttpFetcherTest, FlakyTest) {
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800669 if (this->test_.IsMock())
adlr@google.comc98a7ed2009-12-04 18:54:03 +0000670 return;
Andrew de los Reyes9bbd1872010-07-16 14:52:29 -0700671 GMainLoop* loop = g_main_loop_new(g_main_context_default(), FALSE);
adlr@google.comc98a7ed2009-12-04 18:54:03 +0000672 {
673 FlakyHttpFetcherTestDelegate delegate;
674 delegate.loop_ = loop;
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800675 scoped_ptr<HttpFetcher> fetcher(this->test_.NewSmallFetcher());
adlr@google.comc98a7ed2009-12-04 18:54:03 +0000676 fetcher->set_delegate(&delegate);
677
Jay Srinivasan43488792012-06-19 00:25:31 -0700678 MockConnectionManager* mock_cm = dynamic_cast<MockConnectionManager*>(
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800679 fetcher->GetSystemState()->connection_manager());
Jay Srinivasan43488792012-06-19 00:25:31 -0700680 EXPECT_CALL(*mock_cm, GetConnectionType(_,_))
681 .WillRepeatedly(DoAll(SetArgumentPointee<1>(kNetWifi), Return(true)));
682 EXPECT_CALL(*mock_cm, IsUpdateAllowedOver(kNetWifi))
683 .WillRepeatedly(Return(true));
684 EXPECT_CALL(*mock_cm, StringForConnectionType(kNetWifi))
685 .WillRepeatedly(Return(flimflam::kTypeWifi));
686
687
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800688 scoped_ptr<HttpServer> server(this->test_.CreateServer());
689 ASSERT_TRUE(server->started_);
adlr@google.comc98a7ed2009-12-04 18:54:03 +0000690
691 StartTransferArgs start_xfer_args = {
692 fetcher.get(),
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800693 LocalServerUrlForPath(StringPrintf("/flaky/%d/%d/%d/%d", kBigLength,
694 kFlakyTruncateLength,
695 kFlakySleepEvery,
696 kFlakySleepSecs))
adlr@google.comc98a7ed2009-12-04 18:54:03 +0000697 };
698
699 g_timeout_add(0, StartTransfer, &start_xfer_args);
700 g_main_loop_run(loop);
701
702 // verify the data we get back
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800703 ASSERT_EQ(kBigLength, delegate.data.size());
704 for (int i = 0; i < kBigLength; i += 10) {
adlr@google.comc98a7ed2009-12-04 18:54:03 +0000705 // Assert so that we don't flood the screen w/ EXPECT errors on failure.
706 ASSERT_EQ(delegate.data.substr(i, 10), "abcdefghij");
707 }
708 }
709 g_main_loop_unref(loop);
710}
711
Andrew de los Reyes9bbd1872010-07-16 14:52:29 -0700712namespace {
713class FailureHttpFetcherTestDelegate : public HttpFetcherDelegate {
714 public:
Jay Srinivasan135a58b2012-07-13 12:46:49 -0700715 FailureHttpFetcherTestDelegate(PythonHttpServer* server)
716 : loop_(NULL),
717 server_(server) {}
718
719 virtual ~FailureHttpFetcherTestDelegate() {
720 if (server_) {
721 LOG(INFO) << "Stopping server in destructor";
722 delete server_;
723 LOG(INFO) << "server stopped";
724 }
725 }
726
Andrew de los Reyes9bbd1872010-07-16 14:52:29 -0700727 virtual void ReceivedBytes(HttpFetcher* fetcher,
728 const char* bytes, int length) {
729 if (server_) {
Jay Srinivasan135a58b2012-07-13 12:46:49 -0700730 LOG(INFO) << "Stopping server in ReceivedBytes";
Andrew de los Reyes9bbd1872010-07-16 14:52:29 -0700731 delete server_;
732 LOG(INFO) << "server stopped";
733 server_ = NULL;
734 }
735 }
736 virtual void TransferComplete(HttpFetcher* fetcher, bool successful) {
737 EXPECT_FALSE(successful);
Darin Petkovcb466212010-08-26 09:40:11 -0700738 EXPECT_EQ(0, fetcher->http_response_code());
Andrew de los Reyes9bbd1872010-07-16 14:52:29 -0700739 g_main_loop_quit(loop_);
740 }
Darin Petkov9ce452b2010-11-17 14:33:28 -0800741 virtual void TransferTerminated(HttpFetcher* fetcher) {
742 ADD_FAILURE();
743 }
Andrew de los Reyes9bbd1872010-07-16 14:52:29 -0700744 GMainLoop* loop_;
745 PythonHttpServer* server_;
746};
747} // namespace {}
748
749
750TYPED_TEST(HttpFetcherTest, FailureTest) {
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800751 if (this->test_.IsMock())
Andrew de los Reyes9bbd1872010-07-16 14:52:29 -0700752 return;
753 GMainLoop* loop = g_main_loop_new(g_main_context_default(), FALSE);
754 {
Jay Srinivasan135a58b2012-07-13 12:46:49 -0700755 FailureHttpFetcherTestDelegate delegate(NULL);
Andrew de los Reyes9bbd1872010-07-16 14:52:29 -0700756 delegate.loop_ = loop;
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800757 scoped_ptr<HttpFetcher> fetcher(this->test_.NewSmallFetcher());
Andrew de los Reyes9bbd1872010-07-16 14:52:29 -0700758 fetcher->set_delegate(&delegate);
759
Jay Srinivasan43488792012-06-19 00:25:31 -0700760 MockConnectionManager* mock_cm = dynamic_cast<MockConnectionManager*>(
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800761 fetcher->GetSystemState()->connection_manager());
Jay Srinivasan43488792012-06-19 00:25:31 -0700762 EXPECT_CALL(*mock_cm, GetConnectionType(_,_))
763 .WillRepeatedly(DoAll(SetArgumentPointee<1>(kNetEthernet), Return(true)));
764 EXPECT_CALL(*mock_cm, IsUpdateAllowedOver(kNetEthernet))
765 .WillRepeatedly(Return(true));
766 EXPECT_CALL(*mock_cm, StringForConnectionType(kNetEthernet))
767 .WillRepeatedly(Return(flimflam::kTypeEthernet));
768
769
Andrew de los Reyes9bbd1872010-07-16 14:52:29 -0700770 StartTransferArgs start_xfer_args = {
771 fetcher.get(),
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800772 LocalServerUrlForPath(this->test_.SmallUrl())
Andrew de los Reyes9bbd1872010-07-16 14:52:29 -0700773 };
774
775 g_timeout_add(0, StartTransfer, &start_xfer_args);
776 g_main_loop_run(loop);
777
778 // Exiting and testing happens in the delegate
779 }
780 g_main_loop_unref(loop);
781}
782
783TYPED_TEST(HttpFetcherTest, ServerDiesTest) {
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800784 if (this->test_.IsMock())
Andrew de los Reyes9bbd1872010-07-16 14:52:29 -0700785 return;
786 GMainLoop* loop = g_main_loop_new(g_main_context_default(), FALSE);
787 {
Jay Srinivasan135a58b2012-07-13 12:46:49 -0700788 FailureHttpFetcherTestDelegate delegate(new PythonHttpServer);
Andrew de los Reyes9bbd1872010-07-16 14:52:29 -0700789 delegate.loop_ = loop;
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800790 scoped_ptr<HttpFetcher> fetcher(this->test_.NewSmallFetcher());
Andrew de los Reyes9bbd1872010-07-16 14:52:29 -0700791 fetcher->set_delegate(&delegate);
792
793 StartTransferArgs start_xfer_args = {
794 fetcher.get(),
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800795 LocalServerUrlForPath(StringPrintf("/flaky/%d/%d/%d/%d", kBigLength,
796 kFlakyTruncateLength,
797 kFlakySleepEvery,
798 kFlakySleepSecs))
Andrew de los Reyes9bbd1872010-07-16 14:52:29 -0700799 };
800
801 g_timeout_add(0, StartTransfer, &start_xfer_args);
802 g_main_loop_run(loop);
803
804 // Exiting and testing happens in the delegate
805 }
806 g_main_loop_unref(loop);
807}
808
Darin Petkov41c2fcf2010-08-25 13:14:48 -0700809namespace {
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800810const HttpResponseCode kRedirectCodes[] = {
811 kHttpResponseMovedPermanently, kHttpResponseFound, kHttpResponseSeeOther,
812 kHttpResponseTempRedirect
813};
Darin Petkov41c2fcf2010-08-25 13:14:48 -0700814
815class RedirectHttpFetcherTestDelegate : public HttpFetcherDelegate {
816 public:
817 RedirectHttpFetcherTestDelegate(bool expected_successful)
818 : expected_successful_(expected_successful) {}
819 virtual void ReceivedBytes(HttpFetcher* fetcher,
820 const char* bytes, int length) {
821 data.append(bytes, length);
822 }
823 virtual void TransferComplete(HttpFetcher* fetcher, bool successful) {
824 EXPECT_EQ(expected_successful_, successful);
Darin Petkovcb466212010-08-26 09:40:11 -0700825 if (expected_successful_)
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800826 EXPECT_EQ(kHttpResponseOk, fetcher->http_response_code());
Darin Petkovcb466212010-08-26 09:40:11 -0700827 else {
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800828 EXPECT_GE(fetcher->http_response_code(), kHttpResponseMovedPermanently);
829 EXPECT_LE(fetcher->http_response_code(), kHttpResponseTempRedirect);
Darin Petkovcb466212010-08-26 09:40:11 -0700830 }
Darin Petkov41c2fcf2010-08-25 13:14:48 -0700831 g_main_loop_quit(loop_);
832 }
Darin Petkov9ce452b2010-11-17 14:33:28 -0800833 virtual void TransferTerminated(HttpFetcher* fetcher) {
834 ADD_FAILURE();
835 }
Darin Petkov41c2fcf2010-08-25 13:14:48 -0700836 bool expected_successful_;
837 string data;
838 GMainLoop* loop_;
839};
840
841// RedirectTest takes ownership of |http_fetcher|.
842void RedirectTest(bool expected_successful,
843 const string& url,
844 HttpFetcher* http_fetcher) {
845 GMainLoop* loop = g_main_loop_new(g_main_context_default(), FALSE);
Jay Srinivasan135a58b2012-07-13 12:46:49 -0700846 {
847 RedirectHttpFetcherTestDelegate delegate(expected_successful);
848 delegate.loop_ = loop;
849 scoped_ptr<HttpFetcher> fetcher(http_fetcher);
850 fetcher->set_delegate(&delegate);
Darin Petkov41c2fcf2010-08-25 13:14:48 -0700851
Jay Srinivasan135a58b2012-07-13 12:46:49 -0700852 MockConnectionManager* mock_cm = dynamic_cast<MockConnectionManager*>(
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800853 fetcher->GetSystemState()->connection_manager());
Jay Srinivasan135a58b2012-07-13 12:46:49 -0700854 EXPECT_CALL(*mock_cm, GetConnectionType(_,_))
855 .WillRepeatedly(DoAll(SetArgumentPointee<1>(kNetEthernet), Return(true)));
856 EXPECT_CALL(*mock_cm, IsUpdateAllowedOver(kNetEthernet))
857 .WillRepeatedly(Return(true));
858 EXPECT_CALL(*mock_cm, StringForConnectionType(kNetEthernet))
859 .WillRepeatedly(Return(flimflam::kTypeEthernet));
Jay Srinivasan43488792012-06-19 00:25:31 -0700860
Jay Srinivasan135a58b2012-07-13 12:46:49 -0700861 StartTransferArgs start_xfer_args =
862 { fetcher.get(), LocalServerUrlForPath(url) };
Darin Petkov41c2fcf2010-08-25 13:14:48 -0700863
Jay Srinivasan135a58b2012-07-13 12:46:49 -0700864 g_timeout_add(0, StartTransfer, &start_xfer_args);
865 g_main_loop_run(loop);
866 if (expected_successful) {
867 // verify the data we get back
868 ASSERT_EQ(kMediumLength, delegate.data.size());
869 for (int i = 0; i < kMediumLength; i += 10) {
870 // Assert so that we don't flood the screen w/ EXPECT errors on failure.
871 ASSERT_EQ(delegate.data.substr(i, 10), "abcdefghij");
872 }
Darin Petkov41c2fcf2010-08-25 13:14:48 -0700873 }
874 }
875 g_main_loop_unref(loop);
876}
877} // namespace {}
878
879TYPED_TEST(HttpFetcherTest, SimpleRedirectTest) {
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800880 if (this->test_.IsMock())
Darin Petkov41c2fcf2010-08-25 13:14:48 -0700881 return;
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800882
883 scoped_ptr<HttpServer> server(this->test_.CreateServer());
884 ASSERT_TRUE(server->started_);
885
Darin Petkov41c2fcf2010-08-25 13:14:48 -0700886 for (size_t c = 0; c < arraysize(kRedirectCodes); ++c) {
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800887 const string url = base::StringPrintf("/redirect/%d/download/%d",
888 kRedirectCodes[c],
889 kMediumLength);
890 RedirectTest(true, url, this->test_.NewLargeFetcher());
Darin Petkov41c2fcf2010-08-25 13:14:48 -0700891 }
892}
893
894TYPED_TEST(HttpFetcherTest, MaxRedirectTest) {
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800895 if (this->test_.IsMock())
Darin Petkov41c2fcf2010-08-25 13:14:48 -0700896 return;
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800897
898 scoped_ptr<HttpServer> server(this->test_.CreateServer());
899 ASSERT_TRUE(server->started_);
900
Darin Petkov41c2fcf2010-08-25 13:14:48 -0700901 string url;
902 for (int r = 0; r < LibcurlHttpFetcher::kMaxRedirects; r++) {
903 url += base::StringPrintf("/redirect/%d",
904 kRedirectCodes[r % arraysize(kRedirectCodes)]);
905 }
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800906 url += base::StringPrintf("/download/%d", kMediumLength);
907 RedirectTest(true, url, this->test_.NewLargeFetcher());
Darin Petkov41c2fcf2010-08-25 13:14:48 -0700908}
909
910TYPED_TEST(HttpFetcherTest, BeyondMaxRedirectTest) {
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800911 if (this->test_.IsMock())
Darin Petkov41c2fcf2010-08-25 13:14:48 -0700912 return;
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800913
914 scoped_ptr<HttpServer> server(this->test_.CreateServer());
915 ASSERT_TRUE(server->started_);
916
Darin Petkov41c2fcf2010-08-25 13:14:48 -0700917 string url;
918 for (int r = 0; r < LibcurlHttpFetcher::kMaxRedirects + 1; r++) {
919 url += base::StringPrintf("/redirect/%d",
920 kRedirectCodes[r % arraysize(kRedirectCodes)]);
921 }
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800922 url += base::StringPrintf("/download/%d", kMediumLength);
923 RedirectTest(false, url, this->test_.NewLargeFetcher());
Darin Petkov41c2fcf2010-08-25 13:14:48 -0700924}
925
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -0700926namespace {
927class MultiHttpFetcherTestDelegate : public HttpFetcherDelegate {
928 public:
929 MultiHttpFetcherTestDelegate(int expected_response_code)
930 : expected_response_code_(expected_response_code) {}
Gilad Arnolde4ad2502011-12-29 17:08:54 -0800931
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -0700932 virtual void ReceivedBytes(HttpFetcher* fetcher,
933 const char* bytes, int length) {
Darin Petkov9ce452b2010-11-17 14:33:28 -0800934 EXPECT_EQ(fetcher, fetcher_.get());
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -0700935 data.append(bytes, length);
936 }
Gilad Arnolde4ad2502011-12-29 17:08:54 -0800937
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -0700938 virtual void TransferComplete(HttpFetcher* fetcher, bool successful) {
Darin Petkov9ce452b2010-11-17 14:33:28 -0800939 EXPECT_EQ(fetcher, fetcher_.get());
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800940 EXPECT_EQ(expected_response_code_ != kHttpResponseUndefined, successful);
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -0700941 if (expected_response_code_ != 0)
942 EXPECT_EQ(expected_response_code_, fetcher->http_response_code());
Darin Petkov9ce452b2010-11-17 14:33:28 -0800943 // Destroy the fetcher (because we're allowed to).
944 fetcher_.reset(NULL);
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -0700945 g_main_loop_quit(loop_);
946 }
Gilad Arnolde4ad2502011-12-29 17:08:54 -0800947
Darin Petkov9ce452b2010-11-17 14:33:28 -0800948 virtual void TransferTerminated(HttpFetcher* fetcher) {
949 ADD_FAILURE();
950 }
Gilad Arnolde4ad2502011-12-29 17:08:54 -0800951
Darin Petkov9ce452b2010-11-17 14:33:28 -0800952 scoped_ptr<HttpFetcher> fetcher_;
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -0700953 int expected_response_code_;
954 string data;
955 GMainLoop* loop_;
956};
957
958void MultiTest(HttpFetcher* fetcher_in,
959 const string& url,
Andrew de los Reyes819fef22010-12-17 11:33:58 -0800960 const vector<pair<off_t, off_t> >& ranges,
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -0700961 const string& expected_prefix,
962 off_t expected_size,
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800963 HttpResponseCode expected_response_code) {
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -0700964 GMainLoop* loop = g_main_loop_new(g_main_context_default(), FALSE);
965 {
966 MultiHttpFetcherTestDelegate delegate(expected_response_code);
967 delegate.loop_ = loop;
Darin Petkov9ce452b2010-11-17 14:33:28 -0800968 delegate.fetcher_.reset(fetcher_in);
Jay Srinivasan43488792012-06-19 00:25:31 -0700969
970 MockConnectionManager* mock_cm = dynamic_cast<MockConnectionManager*>(
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800971 fetcher_in->GetSystemState()->connection_manager());
Jay Srinivasan43488792012-06-19 00:25:31 -0700972 EXPECT_CALL(*mock_cm, GetConnectionType(_,_))
973 .WillRepeatedly(DoAll(SetArgumentPointee<1>(kNetWifi), Return(true)));
974 EXPECT_CALL(*mock_cm, IsUpdateAllowedOver(kNetWifi))
975 .WillRepeatedly(Return(true));
976 EXPECT_CALL(*mock_cm, StringForConnectionType(kNetWifi))
977 .WillRepeatedly(Return(flimflam::kTypeWifi));
978
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800979 MultiRangeHttpFetcher* multi_fetcher =
980 dynamic_cast<MultiRangeHttpFetcher*>(fetcher_in);
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -0700981 ASSERT_TRUE(multi_fetcher);
Andrew de los Reyes819fef22010-12-17 11:33:58 -0800982 multi_fetcher->ClearRanges();
983 for (vector<pair<off_t, off_t> >::const_iterator it = ranges.begin(),
984 e = ranges.end(); it != e; ++it) {
Gilad Arnolde4ad2502011-12-29 17:08:54 -0800985 std::string tmp_str = StringPrintf("%jd+", it->first);
986 if (it->second > 0) {
987 base::StringAppendF(&tmp_str, "%jd", it->second);
988 multi_fetcher->AddRange(it->first, it->second);
989 } else {
990 base::StringAppendF(&tmp_str, "?");
991 multi_fetcher->AddRange(it->first);
992 }
993 LOG(INFO) << "added range: " << tmp_str;
Andrew de los Reyes819fef22010-12-17 11:33:58 -0800994 }
Darin Petkovfc7a0ce2010-10-25 10:38:37 -0700995 multi_fetcher->SetBuildType(false);
Darin Petkov9ce452b2010-11-17 14:33:28 -0800996 multi_fetcher->set_delegate(&delegate);
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -0700997
Darin Petkov9ce452b2010-11-17 14:33:28 -0800998 StartTransferArgs start_xfer_args = {multi_fetcher, url};
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -0700999
1000 g_timeout_add(0, StartTransfer, &start_xfer_args);
1001 g_main_loop_run(loop);
1002
1003 EXPECT_EQ(expected_size, delegate.data.size());
1004 EXPECT_EQ(expected_prefix,
1005 string(delegate.data.data(), expected_prefix.size()));
1006 }
1007 g_main_loop_unref(loop);
1008}
1009} // namespace {}
1010
Darin Petkov9ce452b2010-11-17 14:33:28 -08001011TYPED_TEST(HttpFetcherTest, MultiHttpFetcherSimpleTest) {
Gilad Arnold9bedeb52011-11-17 16:19:57 -08001012 if (!this->test_.IsMulti())
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -07001013 return;
Gilad Arnold9bedeb52011-11-17 16:19:57 -08001014
1015 scoped_ptr<HttpServer> server(this->test_.CreateServer());
1016 ASSERT_TRUE(server->started_);
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -07001017
Andrew de los Reyes819fef22010-12-17 11:33:58 -08001018 vector<pair<off_t, off_t> > ranges;
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -07001019 ranges.push_back(make_pair(0, 25));
Gilad Arnolde4ad2502011-12-29 17:08:54 -08001020 ranges.push_back(make_pair(99, 0));
Gilad Arnold9bedeb52011-11-17 16:19:57 -08001021 MultiTest(this->test_.NewLargeFetcher(),
1022 this->test_.BigUrl(),
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -07001023 ranges,
1024 "abcdefghijabcdefghijabcdejabcdefghijabcdef",
Gilad Arnold9bedeb52011-11-17 16:19:57 -08001025 kBigLength - (99 - 25),
1026 kHttpResponsePartialContent);
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -07001027}
1028
1029TYPED_TEST(HttpFetcherTest, MultiHttpFetcherLengthLimitTest) {
Gilad Arnold9bedeb52011-11-17 16:19:57 -08001030 if (!this->test_.IsMulti())
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -07001031 return;
Gilad Arnold9bedeb52011-11-17 16:19:57 -08001032
1033 scoped_ptr<HttpServer> server(this->test_.CreateServer());
1034 ASSERT_TRUE(server->started_);
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -07001035
Andrew de los Reyes819fef22010-12-17 11:33:58 -08001036 vector<pair<off_t, off_t> > ranges;
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -07001037 ranges.push_back(make_pair(0, 24));
Gilad Arnold9bedeb52011-11-17 16:19:57 -08001038 MultiTest(this->test_.NewLargeFetcher(),
1039 this->test_.BigUrl(),
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -07001040 ranges,
1041 "abcdefghijabcdefghijabcd",
1042 24,
Gilad Arnolde4ad2502011-12-29 17:08:54 -08001043 kHttpResponsePartialContent);
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -07001044}
1045
1046TYPED_TEST(HttpFetcherTest, MultiHttpFetcherMultiEndTest) {
Gilad Arnold9bedeb52011-11-17 16:19:57 -08001047 if (!this->test_.IsMulti())
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -07001048 return;
Gilad Arnold9bedeb52011-11-17 16:19:57 -08001049
1050 scoped_ptr<HttpServer> server(this->test_.CreateServer());
1051 ASSERT_TRUE(server->started_);
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -07001052
Andrew de los Reyes819fef22010-12-17 11:33:58 -08001053 vector<pair<off_t, off_t> > ranges;
Gilad Arnolde4ad2502011-12-29 17:08:54 -08001054 ranges.push_back(make_pair(kBigLength - 2, 0));
1055 ranges.push_back(make_pair(kBigLength - 3, 0));
Gilad Arnold9bedeb52011-11-17 16:19:57 -08001056 MultiTest(this->test_.NewLargeFetcher(),
1057 this->test_.BigUrl(),
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -07001058 ranges,
1059 "ijhij",
1060 5,
Gilad Arnold9bedeb52011-11-17 16:19:57 -08001061 kHttpResponsePartialContent);
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -07001062}
1063
1064TYPED_TEST(HttpFetcherTest, MultiHttpFetcherInsufficientTest) {
Gilad Arnold9bedeb52011-11-17 16:19:57 -08001065 if (!this->test_.IsMulti())
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -07001066 return;
Gilad Arnold9bedeb52011-11-17 16:19:57 -08001067
1068 scoped_ptr<HttpServer> server(this->test_.CreateServer());
1069 ASSERT_TRUE(server->started_);
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -07001070
Andrew de los Reyes819fef22010-12-17 11:33:58 -08001071 vector<pair<off_t, off_t> > ranges;
Gilad Arnold9bedeb52011-11-17 16:19:57 -08001072 ranges.push_back(make_pair(kBigLength - 2, 4));
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -07001073 for (int i = 0; i < 2; ++i) {
Andrew de los Reyes819fef22010-12-17 11:33:58 -08001074 LOG(INFO) << "i = " << i;
Gilad Arnold9bedeb52011-11-17 16:19:57 -08001075 MultiTest(this->test_.NewLargeFetcher(),
1076 this->test_.BigUrl(),
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -07001077 ranges,
1078 "ij",
1079 2,
Gilad Arnold9bedeb52011-11-17 16:19:57 -08001080 kHttpResponseUndefined);
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -07001081 ranges.push_back(make_pair(0, 5));
1082 }
1083}
1084
Gilad Arnold9bedeb52011-11-17 16:19:57 -08001085// Issue #18143: when a fetch of a secondary chunk out of a chain, then it
1086// should retry with other proxies listed before giving up.
1087//
1088// (1) successful recovery: The offset fetch will fail twice but succeed with
1089// the third proxy.
1090TYPED_TEST(HttpFetcherTest, MultiHttpFetcherErrorIfOffsetRecoverableTest) {
1091 if (!this->test_.IsMulti())
1092 return;
1093
1094 scoped_ptr<HttpServer> server(this->test_.CreateServer());
1095 ASSERT_TRUE(server->started_);
1096
1097 vector<pair<off_t, off_t> > ranges;
1098 ranges.push_back(make_pair(0, 25));
Gilad Arnolde4ad2502011-12-29 17:08:54 -08001099 ranges.push_back(make_pair(99, 0));
Gilad Arnold9bedeb52011-11-17 16:19:57 -08001100 MultiTest(this->test_.NewLargeFetcher(3),
1101 LocalServerUrlForPath(base::StringPrintf("/error-if-offset/%d/2",
1102 kBigLength)),
1103 ranges,
1104 "abcdefghijabcdefghijabcdejabcdefghijabcdef",
1105 kBigLength - (99 - 25),
1106 kHttpResponsePartialContent);
1107}
1108
1109// (2) unsuccessful recovery: The offset fetch will fail repeatedly. The
1110// fetcher will signal a (failed) completed transfer to the delegate.
1111TYPED_TEST(HttpFetcherTest, MultiHttpFetcherErrorIfOffsetUnrecoverableTest) {
1112 if (!this->test_.IsMulti())
1113 return;
1114
1115 scoped_ptr<HttpServer> server(this->test_.CreateServer());
1116 ASSERT_TRUE(server->started_);
1117
1118 vector<pair<off_t, off_t> > ranges;
1119 ranges.push_back(make_pair(0, 25));
Gilad Arnolde4ad2502011-12-29 17:08:54 -08001120 ranges.push_back(make_pair(99, 0));
Gilad Arnold9bedeb52011-11-17 16:19:57 -08001121 MultiTest(this->test_.NewLargeFetcher(2),
1122 LocalServerUrlForPath(base::StringPrintf("/error-if-offset/%d/3",
1123 kBigLength)),
1124 ranges,
1125 "abcdefghijabcdefghijabcde", // only received the first chunk
1126 25,
1127 kHttpResponseUndefined);
1128}
1129
1130
1131
Andrew de los Reyesd57d1472010-10-21 13:34:08 -07001132namespace {
Darin Petkovfc7a0ce2010-10-25 10:38:37 -07001133class BlockedTransferTestDelegate : public HttpFetcherDelegate {
Andrew de los Reyesd57d1472010-10-21 13:34:08 -07001134 public:
1135 virtual void ReceivedBytes(HttpFetcher* fetcher,
1136 const char* bytes, int length) {
1137 ADD_FAILURE();
1138 }
1139 virtual void TransferComplete(HttpFetcher* fetcher, bool successful) {
1140 EXPECT_FALSE(successful);
1141 g_main_loop_quit(loop_);
1142 }
Darin Petkov9ce452b2010-11-17 14:33:28 -08001143 virtual void TransferTerminated(HttpFetcher* fetcher) {
1144 ADD_FAILURE();
1145 }
Andrew de los Reyesd57d1472010-10-21 13:34:08 -07001146 GMainLoop* loop_;
1147};
1148
1149} // namespace
1150
Darin Petkovfc7a0ce2010-10-25 10:38:37 -07001151TYPED_TEST(HttpFetcherTest, BlockedTransferTest) {
Gilad Arnold9bedeb52011-11-17 16:19:57 -08001152 if (this->test_.IsMock() || this->test_.IsMulti())
Andrew de los Reyesd57d1472010-10-21 13:34:08 -07001153 return;
Andrew de los Reyesd57d1472010-10-21 13:34:08 -07001154
Darin Petkovfc7a0ce2010-10-25 10:38:37 -07001155 for (int i = 0; i < 2; i++) {
Gilad Arnold9bedeb52011-11-17 16:19:57 -08001156 scoped_ptr<HttpServer> server(this->test_.CreateServer());
1157 ASSERT_TRUE(server->started_);
Andrew de los Reyesd57d1472010-10-21 13:34:08 -07001158
Darin Petkovfc7a0ce2010-10-25 10:38:37 -07001159 GMainLoop* loop = g_main_loop_new(g_main_context_default(), FALSE);
Jay Srinivasan135a58b2012-07-13 12:46:49 -07001160 {
1161 BlockedTransferTestDelegate delegate;
1162 delegate.loop_ = loop;
Andrew de los Reyesd57d1472010-10-21 13:34:08 -07001163
Jay Srinivasan135a58b2012-07-13 12:46:49 -07001164 bool is_allowed = (i != 0);
1165 scoped_ptr<HttpFetcher> fetcher(this->test_.NewLargeFetcher());
1166 MockConnectionManager* mock_cm = dynamic_cast<MockConnectionManager*>(
Jay Srinivasan6f6ea002012-12-14 11:26:28 -08001167 fetcher->GetSystemState()->connection_manager());
Jay Srinivasan135a58b2012-07-13 12:46:49 -07001168 EXPECT_CALL(*mock_cm, GetConnectionType(_,_))
1169 .WillRepeatedly(DoAll(SetArgumentPointee<1>(kNetWifi), Return(true)));
1170 EXPECT_CALL(*mock_cm, IsUpdateAllowedOver(kNetWifi))
1171 .WillRepeatedly(Return(is_allowed));
1172 EXPECT_CALL(*mock_cm, StringForConnectionType(kNetWifi))
1173 .WillRepeatedly(Return(flimflam::kTypeWifi));
Jay Srinivasan43488792012-06-19 00:25:31 -07001174
Jay Srinivasan135a58b2012-07-13 12:46:49 -07001175 bool is_official_build = (i == 1);
1176 LOG(INFO) << "is_update_allowed_over_connection: " << is_allowed;
1177 LOG(INFO) << "is_official_build: " << is_official_build;
1178 fetcher->SetBuildType(is_official_build);
1179 fetcher->set_delegate(&delegate);
Darin Petkovfc7a0ce2010-10-25 10:38:37 -07001180
Jay Srinivasan135a58b2012-07-13 12:46:49 -07001181 StartTransferArgs start_xfer_args =
1182 { fetcher.get(), LocalServerUrlForPath(this->test_.SmallUrl()) };
Darin Petkovfc7a0ce2010-10-25 10:38:37 -07001183
Jay Srinivasan135a58b2012-07-13 12:46:49 -07001184 g_timeout_add(0, StartTransfer, &start_xfer_args);
1185 g_main_loop_run(loop);
1186 }
Darin Petkovfc7a0ce2010-10-25 10:38:37 -07001187 g_main_loop_unref(loop);
1188 }
Andrew de los Reyesd57d1472010-10-21 13:34:08 -07001189}
1190
rspangler@google.com49fdf182009-10-10 00:57:34 +00001191} // namespace chromeos_update_engine