blob: 4fb890303abb7b5bc2bbc756a2e4965fb34ba90e [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;
325 }
326};
327
328// Test case types list.
329typedef ::testing::Types<LibcurlHttpFetcherTest,
330 MockHttpFetcherTest,
331 MultiRangeHttpFetcherTest> HttpFetcherTestTypes;
rspangler@google.com49fdf182009-10-10 00:57:34 +0000332TYPED_TEST_CASE(HttpFetcherTest, HttpFetcherTestTypes);
333
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800334
rspangler@google.com49fdf182009-10-10 00:57:34 +0000335namespace {
336class HttpFetcherTestDelegate : public HttpFetcherDelegate {
adlr@google.comc98a7ed2009-12-04 18:54:03 +0000337 public:
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800338 HttpFetcherTestDelegate() :
Gilad Arnold48085ba2011-11-16 09:36:08 -0800339 is_expect_error_(false), times_transfer_complete_called_(0),
340 times_transfer_terminated_called_(0), times_received_bytes_called_(0) {}
341
rspangler@google.com49fdf182009-10-10 00:57:34 +0000342 virtual void ReceivedBytes(HttpFetcher* fetcher,
343 const char* bytes, int length) {
344 char str[length + 1];
345 memset(str, 0, length + 1);
346 memcpy(str, bytes, length);
Gilad Arnold48085ba2011-11-16 09:36:08 -0800347
348 // Update counters
349 times_received_bytes_called_++;
rspangler@google.com49fdf182009-10-10 00:57:34 +0000350 }
Gilad Arnold48085ba2011-11-16 09:36:08 -0800351
rspangler@google.com49fdf182009-10-10 00:57:34 +0000352 virtual void TransferComplete(HttpFetcher* fetcher, bool successful) {
Gilad Arnold48085ba2011-11-16 09:36:08 -0800353 if (is_expect_error_)
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800354 EXPECT_EQ(kHttpResponseNotFound, fetcher->http_response_code());
Gilad Arnold48085ba2011-11-16 09:36:08 -0800355 else
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800356 EXPECT_EQ(kHttpResponseOk, fetcher->http_response_code());
rspangler@google.com49fdf182009-10-10 00:57:34 +0000357 g_main_loop_quit(loop_);
Gilad Arnold48085ba2011-11-16 09:36:08 -0800358
359 // Update counter
360 times_transfer_complete_called_++;
rspangler@google.com49fdf182009-10-10 00:57:34 +0000361 }
Gilad Arnold48085ba2011-11-16 09:36:08 -0800362
Darin Petkov9ce452b2010-11-17 14:33:28 -0800363 virtual void TransferTerminated(HttpFetcher* fetcher) {
364 ADD_FAILURE();
Gilad Arnold48085ba2011-11-16 09:36:08 -0800365 times_transfer_terminated_called_++;
Darin Petkov9ce452b2010-11-17 14:33:28 -0800366 }
Gilad Arnold48085ba2011-11-16 09:36:08 -0800367
rspangler@google.com49fdf182009-10-10 00:57:34 +0000368 GMainLoop* loop_;
Gilad Arnold48085ba2011-11-16 09:36:08 -0800369
370 // Are we expecting an error response? (default: no)
371 bool is_expect_error_;
372
373 // Counters for callback invocations.
374 int times_transfer_complete_called_;
375 int times_transfer_terminated_called_;
376 int times_received_bytes_called_;
rspangler@google.com49fdf182009-10-10 00:57:34 +0000377};
adlr@google.comc98a7ed2009-12-04 18:54:03 +0000378
379struct StartTransferArgs {
380 HttpFetcher *http_fetcher;
381 string url;
382};
383
384gboolean StartTransfer(gpointer data) {
385 StartTransferArgs *args = reinterpret_cast<StartTransferArgs*>(data);
386 args->http_fetcher->BeginTransfer(args->url);
387 return FALSE;
388}
rspangler@google.com49fdf182009-10-10 00:57:34 +0000389} // namespace {}
390
391TYPED_TEST(HttpFetcherTest, SimpleTest) {
Andrew de los Reyes9bbd1872010-07-16 14:52:29 -0700392 GMainLoop* loop = g_main_loop_new(g_main_context_default(), FALSE);
rspangler@google.com49fdf182009-10-10 00:57:34 +0000393 {
394 HttpFetcherTestDelegate delegate;
395 delegate.loop_ = loop;
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800396 scoped_ptr<HttpFetcher> fetcher(this->test_.NewSmallFetcher());
rspangler@google.com49fdf182009-10-10 00:57:34 +0000397 fetcher->set_delegate(&delegate);
398
Jay Srinivasan43488792012-06-19 00:25:31 -0700399 MockConnectionManager* mock_cm = dynamic_cast<MockConnectionManager*>(
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800400 fetcher->GetSystemState()->connection_manager());
Jay Srinivasan43488792012-06-19 00:25:31 -0700401 EXPECT_CALL(*mock_cm, GetConnectionType(_,_))
402 .WillRepeatedly(DoAll(SetArgumentPointee<1>(kNetWifi), Return(true)));
403 EXPECT_CALL(*mock_cm, IsUpdateAllowedOver(kNetWifi))
404 .WillRepeatedly(Return(true));
405 EXPECT_CALL(*mock_cm, StringForConnectionType(kNetWifi))
406 .WillRepeatedly(Return(flimflam::kTypeWifi));
407
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800408 scoped_ptr<HttpServer> server(this->test_.CreateServer());
409 ASSERT_TRUE(server->started_);
rspangler@google.com49fdf182009-10-10 00:57:34 +0000410
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800411 StartTransferArgs start_xfer_args = {fetcher.get(), this->test_.SmallUrl()};
adlr@google.comc98a7ed2009-12-04 18:54:03 +0000412
413 g_timeout_add(0, StartTransfer, &start_xfer_args);
rspangler@google.com49fdf182009-10-10 00:57:34 +0000414 g_main_loop_run(loop);
415 }
416 g_main_loop_unref(loop);
417}
418
Andrew de los Reyes3270f742010-07-15 22:28:14 -0700419TYPED_TEST(HttpFetcherTest, SimpleBigTest) {
Andrew de los Reyes9bbd1872010-07-16 14:52:29 -0700420 GMainLoop* loop = g_main_loop_new(g_main_context_default(), FALSE);
Andrew de los Reyes3270f742010-07-15 22:28:14 -0700421 {
422 HttpFetcherTestDelegate delegate;
423 delegate.loop_ = loop;
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800424 scoped_ptr<HttpFetcher> fetcher(this->test_.NewLargeFetcher());
Andrew de los Reyes3270f742010-07-15 22:28:14 -0700425 fetcher->set_delegate(&delegate);
426
Jay Srinivasan43488792012-06-19 00:25:31 -0700427 MockConnectionManager* mock_cm = dynamic_cast<MockConnectionManager*>(
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800428 fetcher->GetSystemState()->connection_manager());
Jay Srinivasan43488792012-06-19 00:25:31 -0700429 EXPECT_CALL(*mock_cm, GetConnectionType(_,_))
430 .WillRepeatedly(DoAll(SetArgumentPointee<1>(kNetEthernet), Return(true)));
431 EXPECT_CALL(*mock_cm, IsUpdateAllowedOver(kNetEthernet))
432 .WillRepeatedly(Return(true));
433 EXPECT_CALL(*mock_cm, StringForConnectionType(kNetEthernet))
434 .WillRepeatedly(Return(flimflam::kTypeEthernet));
435
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800436 scoped_ptr<HttpServer> server(this->test_.CreateServer());
437 ASSERT_TRUE(server->started_);
Andrew de los Reyes3270f742010-07-15 22:28:14 -0700438
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800439 StartTransferArgs start_xfer_args = {fetcher.get(), this->test_.BigUrl()};
Andrew de los Reyes3270f742010-07-15 22:28:14 -0700440
441 g_timeout_add(0, StartTransfer, &start_xfer_args);
442 g_main_loop_run(loop);
443 }
444 g_main_loop_unref(loop);
445}
446
Gilad Arnold48085ba2011-11-16 09:36:08 -0800447// Issue #9648: when server returns an error HTTP response, the fetcher needs to
448// terminate transfer prematurely, rather than try to process the error payload.
449TYPED_TEST(HttpFetcherTest, ErrorTest) {
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800450 if (this->test_.IsMock() || this->test_.IsMulti())
Gilad Arnold48085ba2011-11-16 09:36:08 -0800451 return;
452 GMainLoop* loop = g_main_loop_new(g_main_context_default(), FALSE);
453 {
454 HttpFetcherTestDelegate delegate;
455 delegate.loop_ = loop;
456
457 // Delegate should expect an error response.
458 delegate.is_expect_error_ = true;
459
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800460 scoped_ptr<HttpFetcher> fetcher(this->test_.NewSmallFetcher());
Gilad Arnold48085ba2011-11-16 09:36:08 -0800461 fetcher->set_delegate(&delegate);
462
Jay Srinivasan43488792012-06-19 00:25:31 -0700463 MockConnectionManager* mock_cm = dynamic_cast<MockConnectionManager*>(
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800464 fetcher->GetSystemState()->connection_manager());
Jay Srinivasan43488792012-06-19 00:25:31 -0700465 EXPECT_CALL(*mock_cm, GetConnectionType(_,_))
466 .WillRepeatedly(DoAll(SetArgumentPointee<1>(kNetWimax), Return(true)));
467 EXPECT_CALL(*mock_cm, IsUpdateAllowedOver(kNetWimax))
468 .WillRepeatedly(Return(true));
469 EXPECT_CALL(*mock_cm, StringForConnectionType(kNetWimax))
470 .WillRepeatedly(Return(flimflam::kTypeWimax));
471
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800472 scoped_ptr<HttpServer> server(this->test_.CreateServer());
473 ASSERT_TRUE(server->started_);
Gilad Arnold48085ba2011-11-16 09:36:08 -0800474
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800475 StartTransferArgs start_xfer_args = {
476 fetcher.get(),
477 this->test_.ErrorUrl()
478 };
Gilad Arnold48085ba2011-11-16 09:36:08 -0800479
480 g_timeout_add(0, StartTransfer, &start_xfer_args);
481 g_main_loop_run(loop);
482
483 // Make sure that no bytes were received.
484 CHECK_EQ(delegate.times_received_bytes_called_, 0);
Mike Frysinger0f9547d2012-02-16 12:11:37 -0500485 CHECK_EQ(fetcher->GetBytesDownloaded(), static_cast<size_t>(0));
Gilad Arnold48085ba2011-11-16 09:36:08 -0800486
487 // Make sure that transfer completion was signaled once, and no termination
488 // was signaled.
489 CHECK_EQ(delegate.times_transfer_complete_called_, 1);
490 CHECK_EQ(delegate.times_transfer_terminated_called_, 0);
491 }
492 g_main_loop_unref(loop);
493}
494
rspangler@google.com49fdf182009-10-10 00:57:34 +0000495namespace {
496class PausingHttpFetcherTestDelegate : public HttpFetcherDelegate {
497 public:
498 virtual void ReceivedBytes(HttpFetcher* fetcher,
499 const char* bytes, int length) {
500 char str[length + 1];
rspangler@google.com49fdf182009-10-10 00:57:34 +0000501 memset(str, 0, length + 1);
502 memcpy(str, bytes, length);
503 CHECK(!paused_);
504 paused_ = true;
505 fetcher->Pause();
rspangler@google.com49fdf182009-10-10 00:57:34 +0000506 }
507 virtual void TransferComplete(HttpFetcher* fetcher, bool successful) {
508 g_main_loop_quit(loop_);
509 }
Darin Petkov9ce452b2010-11-17 14:33:28 -0800510 virtual void TransferTerminated(HttpFetcher* fetcher) {
511 ADD_FAILURE();
512 }
rspangler@google.com49fdf182009-10-10 00:57:34 +0000513 void Unpause() {
514 CHECK(paused_);
515 paused_ = false;
516 fetcher_->Unpause();
rspangler@google.com49fdf182009-10-10 00:57:34 +0000517 }
518 bool paused_;
519 HttpFetcher* fetcher_;
520 GMainLoop* loop_;
521};
522
523gboolean UnpausingTimeoutCallback(gpointer data) {
524 PausingHttpFetcherTestDelegate *delegate =
525 reinterpret_cast<PausingHttpFetcherTestDelegate*>(data);
526 if (delegate->paused_)
527 delegate->Unpause();
528 return TRUE;
529}
530} // namespace {}
531
532TYPED_TEST(HttpFetcherTest, PauseTest) {
Andrew de los Reyes9bbd1872010-07-16 14:52:29 -0700533 GMainLoop* loop = g_main_loop_new(g_main_context_default(), FALSE);
rspangler@google.com49fdf182009-10-10 00:57:34 +0000534 {
535 PausingHttpFetcherTestDelegate delegate;
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800536 scoped_ptr<HttpFetcher> fetcher(this->test_.NewLargeFetcher());
rspangler@google.com49fdf182009-10-10 00:57:34 +0000537 delegate.paused_ = false;
538 delegate.loop_ = loop;
539 delegate.fetcher_ = fetcher.get();
540 fetcher->set_delegate(&delegate);
541
Jay Srinivasan43488792012-06-19 00:25:31 -0700542 MockConnectionManager* mock_cm = dynamic_cast<MockConnectionManager*>(
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800543 fetcher->GetSystemState()->connection_manager());
Jay Srinivasan43488792012-06-19 00:25:31 -0700544 EXPECT_CALL(*mock_cm, GetConnectionType(_,_))
545 .WillRepeatedly(DoAll(SetArgumentPointee<1>(kNetCellular), Return(true)));
546 EXPECT_CALL(*mock_cm, IsUpdateAllowedOver(kNetCellular))
547 .WillRepeatedly(Return(true));
548 EXPECT_CALL(*mock_cm, StringForConnectionType(kNetCellular))
549 .WillRepeatedly(Return(flimflam::kTypeCellular));
550
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800551 scoped_ptr<HttpServer> server(this->test_.CreateServer());
552 ASSERT_TRUE(server->started_);
Andrew de los Reyesf3ed8e72011-02-16 10:35:46 -0800553
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800554 guint callback_id = g_timeout_add(kHttpResponseInternalServerError,
555 UnpausingTimeoutCallback, &delegate);
556 fetcher->BeginTransfer(this->test_.BigUrl());
rspangler@google.com49fdf182009-10-10 00:57:34 +0000557
558 g_main_loop_run(loop);
Andrew de los Reyesf3ed8e72011-02-16 10:35:46 -0800559 g_source_remove(callback_id);
rspangler@google.com49fdf182009-10-10 00:57:34 +0000560 }
561 g_main_loop_unref(loop);
562}
563
564namespace {
565class AbortingHttpFetcherTestDelegate : public HttpFetcherDelegate {
566 public:
567 virtual void ReceivedBytes(HttpFetcher* fetcher,
568 const char* bytes, int length) {}
569 virtual void TransferComplete(HttpFetcher* fetcher, bool successful) {
Darin Petkov9ce452b2010-11-17 14:33:28 -0800570 ADD_FAILURE(); // We should never get here
rspangler@google.com49fdf182009-10-10 00:57:34 +0000571 g_main_loop_quit(loop_);
572 }
Darin Petkov9ce452b2010-11-17 14:33:28 -0800573 virtual void TransferTerminated(HttpFetcher* fetcher) {
574 EXPECT_EQ(fetcher, fetcher_.get());
575 EXPECT_FALSE(once_);
576 EXPECT_TRUE(callback_once_);
577 callback_once_ = false;
578 // |fetcher| can be destroyed during this callback.
579 fetcher_.reset(NULL);
Andrew de los Reyes819fef22010-12-17 11:33:58 -0800580 }
rspangler@google.com49fdf182009-10-10 00:57:34 +0000581 void TerminateTransfer() {
582 CHECK(once_);
583 once_ = false;
584 fetcher_->TerminateTransfer();
585 }
586 void EndLoop() {
587 g_main_loop_quit(loop_);
588 }
589 bool once_;
Darin Petkov9ce452b2010-11-17 14:33:28 -0800590 bool callback_once_;
591 scoped_ptr<HttpFetcher> fetcher_;
rspangler@google.com49fdf182009-10-10 00:57:34 +0000592 GMainLoop* loop_;
593};
594
595gboolean AbortingTimeoutCallback(gpointer data) {
596 AbortingHttpFetcherTestDelegate *delegate =
597 reinterpret_cast<AbortingHttpFetcherTestDelegate*>(data);
598 if (delegate->once_) {
599 delegate->TerminateTransfer();
600 return TRUE;
601 } else {
602 delegate->EndLoop();
603 return FALSE;
604 }
605}
606} // namespace {}
607
608TYPED_TEST(HttpFetcherTest, AbortTest) {
Andrew de los Reyes9bbd1872010-07-16 14:52:29 -0700609 GMainLoop* loop = g_main_loop_new(g_main_context_default(), FALSE);
rspangler@google.com49fdf182009-10-10 00:57:34 +0000610 {
611 AbortingHttpFetcherTestDelegate delegate;
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800612 delegate.fetcher_.reset(this->test_.NewLargeFetcher());
rspangler@google.com49fdf182009-10-10 00:57:34 +0000613 delegate.once_ = true;
Darin Petkov9ce452b2010-11-17 14:33:28 -0800614 delegate.callback_once_ = true;
rspangler@google.com49fdf182009-10-10 00:57:34 +0000615 delegate.loop_ = loop;
Darin Petkov9ce452b2010-11-17 14:33:28 -0800616 delegate.fetcher_->set_delegate(&delegate);
rspangler@google.com49fdf182009-10-10 00:57:34 +0000617
Jay Srinivasan43488792012-06-19 00:25:31 -0700618 MockConnectionManager* mock_cm = dynamic_cast<MockConnectionManager*>(
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800619 delegate.fetcher_->GetSystemState()->connection_manager());
Jay Srinivasan43488792012-06-19 00:25:31 -0700620 EXPECT_CALL(*mock_cm, GetConnectionType(_,_))
621 .WillRepeatedly(DoAll(SetArgumentPointee<1>(kNetWifi), Return(true)));
622 EXPECT_CALL(*mock_cm, IsUpdateAllowedOver(kNetWifi))
623 .WillRepeatedly(Return(true));
624 EXPECT_CALL(*mock_cm, StringForConnectionType(kNetWifi))
625 .WillRepeatedly(Return(flimflam::kTypeWifi));
626
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800627 scoped_ptr<HttpServer> server(this->test_.CreateServer());
628 this->test_.IgnoreServerAborting(server.get());
629 ASSERT_TRUE(server->started_);
630
rspangler@google.com49fdf182009-10-10 00:57:34 +0000631 GSource* timeout_source_;
632 timeout_source_ = g_timeout_source_new(0); // ms
633 g_source_set_callback(timeout_source_, AbortingTimeoutCallback, &delegate,
634 NULL);
635 g_source_attach(timeout_source_, NULL);
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800636 delegate.fetcher_->BeginTransfer(this->test_.BigUrl());
rspangler@google.com49fdf182009-10-10 00:57:34 +0000637
638 g_main_loop_run(loop);
Darin Petkov9ce452b2010-11-17 14:33:28 -0800639 CHECK(!delegate.once_);
640 CHECK(!delegate.callback_once_);
rspangler@google.com49fdf182009-10-10 00:57:34 +0000641 g_source_destroy(timeout_source_);
642 }
643 g_main_loop_unref(loop);
644}
645
adlr@google.comc98a7ed2009-12-04 18:54:03 +0000646namespace {
647class FlakyHttpFetcherTestDelegate : public HttpFetcherDelegate {
648 public:
649 virtual void ReceivedBytes(HttpFetcher* fetcher,
650 const char* bytes, int length) {
651 data.append(bytes, length);
652 }
653 virtual void TransferComplete(HttpFetcher* fetcher, bool successful) {
Andrew de los Reyesfb4ad7d2010-07-19 10:43:46 -0700654 EXPECT_TRUE(successful);
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800655 EXPECT_EQ(kHttpResponsePartialContent, fetcher->http_response_code());
adlr@google.comc98a7ed2009-12-04 18:54:03 +0000656 g_main_loop_quit(loop_);
657 }
Darin Petkov9ce452b2010-11-17 14:33:28 -0800658 virtual void TransferTerminated(HttpFetcher* fetcher) {
659 ADD_FAILURE();
660 }
adlr@google.comc98a7ed2009-12-04 18:54:03 +0000661 string data;
662 GMainLoop* loop_;
663};
664} // namespace {}
665
666TYPED_TEST(HttpFetcherTest, FlakyTest) {
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800667 if (this->test_.IsMock())
adlr@google.comc98a7ed2009-12-04 18:54:03 +0000668 return;
Andrew de los Reyes9bbd1872010-07-16 14:52:29 -0700669 GMainLoop* loop = g_main_loop_new(g_main_context_default(), FALSE);
adlr@google.comc98a7ed2009-12-04 18:54:03 +0000670 {
671 FlakyHttpFetcherTestDelegate delegate;
672 delegate.loop_ = loop;
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800673 scoped_ptr<HttpFetcher> fetcher(this->test_.NewSmallFetcher());
adlr@google.comc98a7ed2009-12-04 18:54:03 +0000674 fetcher->set_delegate(&delegate);
675
Jay Srinivasan43488792012-06-19 00:25:31 -0700676 MockConnectionManager* mock_cm = dynamic_cast<MockConnectionManager*>(
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800677 fetcher->GetSystemState()->connection_manager());
Jay Srinivasan43488792012-06-19 00:25:31 -0700678 EXPECT_CALL(*mock_cm, GetConnectionType(_,_))
679 .WillRepeatedly(DoAll(SetArgumentPointee<1>(kNetWifi), Return(true)));
680 EXPECT_CALL(*mock_cm, IsUpdateAllowedOver(kNetWifi))
681 .WillRepeatedly(Return(true));
682 EXPECT_CALL(*mock_cm, StringForConnectionType(kNetWifi))
683 .WillRepeatedly(Return(flimflam::kTypeWifi));
684
685
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800686 scoped_ptr<HttpServer> server(this->test_.CreateServer());
687 ASSERT_TRUE(server->started_);
adlr@google.comc98a7ed2009-12-04 18:54:03 +0000688
689 StartTransferArgs start_xfer_args = {
690 fetcher.get(),
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800691 LocalServerUrlForPath(StringPrintf("/flaky/%d/%d/%d/%d", kBigLength,
692 kFlakyTruncateLength,
693 kFlakySleepEvery,
694 kFlakySleepSecs))
adlr@google.comc98a7ed2009-12-04 18:54:03 +0000695 };
696
697 g_timeout_add(0, StartTransfer, &start_xfer_args);
698 g_main_loop_run(loop);
699
700 // verify the data we get back
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800701 ASSERT_EQ(kBigLength, delegate.data.size());
702 for (int i = 0; i < kBigLength; i += 10) {
adlr@google.comc98a7ed2009-12-04 18:54:03 +0000703 // Assert so that we don't flood the screen w/ EXPECT errors on failure.
704 ASSERT_EQ(delegate.data.substr(i, 10), "abcdefghij");
705 }
706 }
707 g_main_loop_unref(loop);
708}
709
Andrew de los Reyes9bbd1872010-07-16 14:52:29 -0700710namespace {
711class FailureHttpFetcherTestDelegate : public HttpFetcherDelegate {
712 public:
Jay Srinivasan135a58b2012-07-13 12:46:49 -0700713 FailureHttpFetcherTestDelegate(PythonHttpServer* server)
714 : loop_(NULL),
715 server_(server) {}
716
717 virtual ~FailureHttpFetcherTestDelegate() {
718 if (server_) {
719 LOG(INFO) << "Stopping server in destructor";
720 delete server_;
721 LOG(INFO) << "server stopped";
722 }
723 }
724
Andrew de los Reyes9bbd1872010-07-16 14:52:29 -0700725 virtual void ReceivedBytes(HttpFetcher* fetcher,
726 const char* bytes, int length) {
727 if (server_) {
Jay Srinivasan135a58b2012-07-13 12:46:49 -0700728 LOG(INFO) << "Stopping server in ReceivedBytes";
Andrew de los Reyes9bbd1872010-07-16 14:52:29 -0700729 delete server_;
730 LOG(INFO) << "server stopped";
731 server_ = NULL;
732 }
733 }
734 virtual void TransferComplete(HttpFetcher* fetcher, bool successful) {
735 EXPECT_FALSE(successful);
Darin Petkovcb466212010-08-26 09:40:11 -0700736 EXPECT_EQ(0, fetcher->http_response_code());
Andrew de los Reyes9bbd1872010-07-16 14:52:29 -0700737 g_main_loop_quit(loop_);
738 }
Darin Petkov9ce452b2010-11-17 14:33:28 -0800739 virtual void TransferTerminated(HttpFetcher* fetcher) {
740 ADD_FAILURE();
741 }
Andrew de los Reyes9bbd1872010-07-16 14:52:29 -0700742 GMainLoop* loop_;
743 PythonHttpServer* server_;
744};
745} // namespace {}
746
747
748TYPED_TEST(HttpFetcherTest, FailureTest) {
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800749 if (this->test_.IsMock())
Andrew de los Reyes9bbd1872010-07-16 14:52:29 -0700750 return;
751 GMainLoop* loop = g_main_loop_new(g_main_context_default(), FALSE);
752 {
Jay Srinivasan135a58b2012-07-13 12:46:49 -0700753 FailureHttpFetcherTestDelegate delegate(NULL);
Andrew de los Reyes9bbd1872010-07-16 14:52:29 -0700754 delegate.loop_ = loop;
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800755 scoped_ptr<HttpFetcher> fetcher(this->test_.NewSmallFetcher());
Andrew de los Reyes9bbd1872010-07-16 14:52:29 -0700756 fetcher->set_delegate(&delegate);
757
Jay Srinivasan43488792012-06-19 00:25:31 -0700758 MockConnectionManager* mock_cm = dynamic_cast<MockConnectionManager*>(
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800759 fetcher->GetSystemState()->connection_manager());
Jay Srinivasan43488792012-06-19 00:25:31 -0700760 EXPECT_CALL(*mock_cm, GetConnectionType(_,_))
761 .WillRepeatedly(DoAll(SetArgumentPointee<1>(kNetEthernet), Return(true)));
762 EXPECT_CALL(*mock_cm, IsUpdateAllowedOver(kNetEthernet))
763 .WillRepeatedly(Return(true));
764 EXPECT_CALL(*mock_cm, StringForConnectionType(kNetEthernet))
765 .WillRepeatedly(Return(flimflam::kTypeEthernet));
766
767
Andrew de los Reyes9bbd1872010-07-16 14:52:29 -0700768 StartTransferArgs start_xfer_args = {
769 fetcher.get(),
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800770 LocalServerUrlForPath(this->test_.SmallUrl())
Andrew de los Reyes9bbd1872010-07-16 14:52:29 -0700771 };
772
773 g_timeout_add(0, StartTransfer, &start_xfer_args);
774 g_main_loop_run(loop);
775
776 // Exiting and testing happens in the delegate
777 }
778 g_main_loop_unref(loop);
779}
780
781TYPED_TEST(HttpFetcherTest, ServerDiesTest) {
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800782 if (this->test_.IsMock())
Andrew de los Reyes9bbd1872010-07-16 14:52:29 -0700783 return;
784 GMainLoop* loop = g_main_loop_new(g_main_context_default(), FALSE);
785 {
Jay Srinivasan135a58b2012-07-13 12:46:49 -0700786 FailureHttpFetcherTestDelegate delegate(new PythonHttpServer);
Andrew de los Reyes9bbd1872010-07-16 14:52:29 -0700787 delegate.loop_ = loop;
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800788 scoped_ptr<HttpFetcher> fetcher(this->test_.NewSmallFetcher());
Andrew de los Reyes9bbd1872010-07-16 14:52:29 -0700789 fetcher->set_delegate(&delegate);
790
791 StartTransferArgs start_xfer_args = {
792 fetcher.get(),
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800793 LocalServerUrlForPath(StringPrintf("/flaky/%d/%d/%d/%d", kBigLength,
794 kFlakyTruncateLength,
795 kFlakySleepEvery,
796 kFlakySleepSecs))
Andrew de los Reyes9bbd1872010-07-16 14:52:29 -0700797 };
798
799 g_timeout_add(0, StartTransfer, &start_xfer_args);
800 g_main_loop_run(loop);
801
802 // Exiting and testing happens in the delegate
803 }
804 g_main_loop_unref(loop);
805}
806
Darin Petkov41c2fcf2010-08-25 13:14:48 -0700807namespace {
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800808const HttpResponseCode kRedirectCodes[] = {
809 kHttpResponseMovedPermanently, kHttpResponseFound, kHttpResponseSeeOther,
810 kHttpResponseTempRedirect
811};
Darin Petkov41c2fcf2010-08-25 13:14:48 -0700812
813class RedirectHttpFetcherTestDelegate : public HttpFetcherDelegate {
814 public:
815 RedirectHttpFetcherTestDelegate(bool expected_successful)
816 : expected_successful_(expected_successful) {}
817 virtual void ReceivedBytes(HttpFetcher* fetcher,
818 const char* bytes, int length) {
819 data.append(bytes, length);
820 }
821 virtual void TransferComplete(HttpFetcher* fetcher, bool successful) {
822 EXPECT_EQ(expected_successful_, successful);
Darin Petkovcb466212010-08-26 09:40:11 -0700823 if (expected_successful_)
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800824 EXPECT_EQ(kHttpResponseOk, fetcher->http_response_code());
Darin Petkovcb466212010-08-26 09:40:11 -0700825 else {
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800826 EXPECT_GE(fetcher->http_response_code(), kHttpResponseMovedPermanently);
827 EXPECT_LE(fetcher->http_response_code(), kHttpResponseTempRedirect);
Darin Petkovcb466212010-08-26 09:40:11 -0700828 }
Darin Petkov41c2fcf2010-08-25 13:14:48 -0700829 g_main_loop_quit(loop_);
830 }
Darin Petkov9ce452b2010-11-17 14:33:28 -0800831 virtual void TransferTerminated(HttpFetcher* fetcher) {
832 ADD_FAILURE();
833 }
Darin Petkov41c2fcf2010-08-25 13:14:48 -0700834 bool expected_successful_;
835 string data;
836 GMainLoop* loop_;
837};
838
839// RedirectTest takes ownership of |http_fetcher|.
840void RedirectTest(bool expected_successful,
841 const string& url,
842 HttpFetcher* http_fetcher) {
843 GMainLoop* loop = g_main_loop_new(g_main_context_default(), FALSE);
Jay Srinivasan135a58b2012-07-13 12:46:49 -0700844 {
845 RedirectHttpFetcherTestDelegate delegate(expected_successful);
846 delegate.loop_ = loop;
847 scoped_ptr<HttpFetcher> fetcher(http_fetcher);
848 fetcher->set_delegate(&delegate);
Darin Petkov41c2fcf2010-08-25 13:14:48 -0700849
Jay Srinivasan135a58b2012-07-13 12:46:49 -0700850 MockConnectionManager* mock_cm = dynamic_cast<MockConnectionManager*>(
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800851 fetcher->GetSystemState()->connection_manager());
Jay Srinivasan135a58b2012-07-13 12:46:49 -0700852 EXPECT_CALL(*mock_cm, GetConnectionType(_,_))
853 .WillRepeatedly(DoAll(SetArgumentPointee<1>(kNetEthernet), Return(true)));
854 EXPECT_CALL(*mock_cm, IsUpdateAllowedOver(kNetEthernet))
855 .WillRepeatedly(Return(true));
856 EXPECT_CALL(*mock_cm, StringForConnectionType(kNetEthernet))
857 .WillRepeatedly(Return(flimflam::kTypeEthernet));
Jay Srinivasan43488792012-06-19 00:25:31 -0700858
Jay Srinivasan135a58b2012-07-13 12:46:49 -0700859 StartTransferArgs start_xfer_args =
860 { fetcher.get(), LocalServerUrlForPath(url) };
Darin Petkov41c2fcf2010-08-25 13:14:48 -0700861
Jay Srinivasan135a58b2012-07-13 12:46:49 -0700862 g_timeout_add(0, StartTransfer, &start_xfer_args);
863 g_main_loop_run(loop);
864 if (expected_successful) {
865 // verify the data we get back
866 ASSERT_EQ(kMediumLength, delegate.data.size());
867 for (int i = 0; i < kMediumLength; i += 10) {
868 // Assert so that we don't flood the screen w/ EXPECT errors on failure.
869 ASSERT_EQ(delegate.data.substr(i, 10), "abcdefghij");
870 }
Darin Petkov41c2fcf2010-08-25 13:14:48 -0700871 }
872 }
873 g_main_loop_unref(loop);
874}
875} // namespace {}
876
877TYPED_TEST(HttpFetcherTest, SimpleRedirectTest) {
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800878 if (this->test_.IsMock())
Darin Petkov41c2fcf2010-08-25 13:14:48 -0700879 return;
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800880
881 scoped_ptr<HttpServer> server(this->test_.CreateServer());
882 ASSERT_TRUE(server->started_);
883
Darin Petkov41c2fcf2010-08-25 13:14:48 -0700884 for (size_t c = 0; c < arraysize(kRedirectCodes); ++c) {
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800885 const string url = base::StringPrintf("/redirect/%d/download/%d",
886 kRedirectCodes[c],
887 kMediumLength);
888 RedirectTest(true, url, this->test_.NewLargeFetcher());
Darin Petkov41c2fcf2010-08-25 13:14:48 -0700889 }
890}
891
892TYPED_TEST(HttpFetcherTest, MaxRedirectTest) {
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800893 if (this->test_.IsMock())
Darin Petkov41c2fcf2010-08-25 13:14:48 -0700894 return;
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800895
896 scoped_ptr<HttpServer> server(this->test_.CreateServer());
897 ASSERT_TRUE(server->started_);
898
Darin Petkov41c2fcf2010-08-25 13:14:48 -0700899 string url;
900 for (int r = 0; r < LibcurlHttpFetcher::kMaxRedirects; r++) {
901 url += base::StringPrintf("/redirect/%d",
902 kRedirectCodes[r % arraysize(kRedirectCodes)]);
903 }
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800904 url += base::StringPrintf("/download/%d", kMediumLength);
905 RedirectTest(true, url, this->test_.NewLargeFetcher());
Darin Petkov41c2fcf2010-08-25 13:14:48 -0700906}
907
908TYPED_TEST(HttpFetcherTest, BeyondMaxRedirectTest) {
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800909 if (this->test_.IsMock())
Darin Petkov41c2fcf2010-08-25 13:14:48 -0700910 return;
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800911
912 scoped_ptr<HttpServer> server(this->test_.CreateServer());
913 ASSERT_TRUE(server->started_);
914
Darin Petkov41c2fcf2010-08-25 13:14:48 -0700915 string url;
916 for (int r = 0; r < LibcurlHttpFetcher::kMaxRedirects + 1; r++) {
917 url += base::StringPrintf("/redirect/%d",
918 kRedirectCodes[r % arraysize(kRedirectCodes)]);
919 }
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800920 url += base::StringPrintf("/download/%d", kMediumLength);
921 RedirectTest(false, url, this->test_.NewLargeFetcher());
Darin Petkov41c2fcf2010-08-25 13:14:48 -0700922}
923
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -0700924namespace {
925class MultiHttpFetcherTestDelegate : public HttpFetcherDelegate {
926 public:
927 MultiHttpFetcherTestDelegate(int expected_response_code)
928 : expected_response_code_(expected_response_code) {}
Gilad Arnolde4ad2502011-12-29 17:08:54 -0800929
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -0700930 virtual void ReceivedBytes(HttpFetcher* fetcher,
931 const char* bytes, int length) {
Darin Petkov9ce452b2010-11-17 14:33:28 -0800932 EXPECT_EQ(fetcher, fetcher_.get());
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -0700933 data.append(bytes, length);
934 }
Gilad Arnolde4ad2502011-12-29 17:08:54 -0800935
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -0700936 virtual void TransferComplete(HttpFetcher* fetcher, bool successful) {
Darin Petkov9ce452b2010-11-17 14:33:28 -0800937 EXPECT_EQ(fetcher, fetcher_.get());
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800938 EXPECT_EQ(expected_response_code_ != kHttpResponseUndefined, successful);
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -0700939 if (expected_response_code_ != 0)
940 EXPECT_EQ(expected_response_code_, fetcher->http_response_code());
Darin Petkov9ce452b2010-11-17 14:33:28 -0800941 // Destroy the fetcher (because we're allowed to).
942 fetcher_.reset(NULL);
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -0700943 g_main_loop_quit(loop_);
944 }
Gilad Arnolde4ad2502011-12-29 17:08:54 -0800945
Darin Petkov9ce452b2010-11-17 14:33:28 -0800946 virtual void TransferTerminated(HttpFetcher* fetcher) {
947 ADD_FAILURE();
948 }
Gilad Arnolde4ad2502011-12-29 17:08:54 -0800949
Darin Petkov9ce452b2010-11-17 14:33:28 -0800950 scoped_ptr<HttpFetcher> fetcher_;
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -0700951 int expected_response_code_;
952 string data;
953 GMainLoop* loop_;
954};
955
956void MultiTest(HttpFetcher* fetcher_in,
957 const string& url,
Andrew de los Reyes819fef22010-12-17 11:33:58 -0800958 const vector<pair<off_t, off_t> >& ranges,
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -0700959 const string& expected_prefix,
960 off_t expected_size,
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800961 HttpResponseCode expected_response_code) {
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -0700962 GMainLoop* loop = g_main_loop_new(g_main_context_default(), FALSE);
963 {
964 MultiHttpFetcherTestDelegate delegate(expected_response_code);
965 delegate.loop_ = loop;
Darin Petkov9ce452b2010-11-17 14:33:28 -0800966 delegate.fetcher_.reset(fetcher_in);
Jay Srinivasan43488792012-06-19 00:25:31 -0700967
968 MockConnectionManager* mock_cm = dynamic_cast<MockConnectionManager*>(
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800969 fetcher_in->GetSystemState()->connection_manager());
Jay Srinivasan43488792012-06-19 00:25:31 -0700970 EXPECT_CALL(*mock_cm, GetConnectionType(_,_))
971 .WillRepeatedly(DoAll(SetArgumentPointee<1>(kNetWifi), Return(true)));
972 EXPECT_CALL(*mock_cm, IsUpdateAllowedOver(kNetWifi))
973 .WillRepeatedly(Return(true));
974 EXPECT_CALL(*mock_cm, StringForConnectionType(kNetWifi))
975 .WillRepeatedly(Return(flimflam::kTypeWifi));
976
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800977 MultiRangeHttpFetcher* multi_fetcher =
978 dynamic_cast<MultiRangeHttpFetcher*>(fetcher_in);
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -0700979 ASSERT_TRUE(multi_fetcher);
Andrew de los Reyes819fef22010-12-17 11:33:58 -0800980 multi_fetcher->ClearRanges();
981 for (vector<pair<off_t, off_t> >::const_iterator it = ranges.begin(),
982 e = ranges.end(); it != e; ++it) {
Gilad Arnolde4ad2502011-12-29 17:08:54 -0800983 std::string tmp_str = StringPrintf("%jd+", it->first);
984 if (it->second > 0) {
985 base::StringAppendF(&tmp_str, "%jd", it->second);
986 multi_fetcher->AddRange(it->first, it->second);
987 } else {
988 base::StringAppendF(&tmp_str, "?");
989 multi_fetcher->AddRange(it->first);
990 }
991 LOG(INFO) << "added range: " << tmp_str;
Andrew de los Reyes819fef22010-12-17 11:33:58 -0800992 }
Darin Petkovfc7a0ce2010-10-25 10:38:37 -0700993 multi_fetcher->SetBuildType(false);
Darin Petkov9ce452b2010-11-17 14:33:28 -0800994 multi_fetcher->set_delegate(&delegate);
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -0700995
Darin Petkov9ce452b2010-11-17 14:33:28 -0800996 StartTransferArgs start_xfer_args = {multi_fetcher, url};
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -0700997
998 g_timeout_add(0, StartTransfer, &start_xfer_args);
999 g_main_loop_run(loop);
1000
1001 EXPECT_EQ(expected_size, delegate.data.size());
1002 EXPECT_EQ(expected_prefix,
1003 string(delegate.data.data(), expected_prefix.size()));
1004 }
1005 g_main_loop_unref(loop);
1006}
1007} // namespace {}
1008
Darin Petkov9ce452b2010-11-17 14:33:28 -08001009TYPED_TEST(HttpFetcherTest, MultiHttpFetcherSimpleTest) {
Gilad Arnold9bedeb52011-11-17 16:19:57 -08001010 if (!this->test_.IsMulti())
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -07001011 return;
Gilad Arnold9bedeb52011-11-17 16:19:57 -08001012
1013 scoped_ptr<HttpServer> server(this->test_.CreateServer());
1014 ASSERT_TRUE(server->started_);
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -07001015
Andrew de los Reyes819fef22010-12-17 11:33:58 -08001016 vector<pair<off_t, off_t> > ranges;
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -07001017 ranges.push_back(make_pair(0, 25));
Gilad Arnolde4ad2502011-12-29 17:08:54 -08001018 ranges.push_back(make_pair(99, 0));
Gilad Arnold9bedeb52011-11-17 16:19:57 -08001019 MultiTest(this->test_.NewLargeFetcher(),
1020 this->test_.BigUrl(),
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -07001021 ranges,
1022 "abcdefghijabcdefghijabcdejabcdefghijabcdef",
Gilad Arnold9bedeb52011-11-17 16:19:57 -08001023 kBigLength - (99 - 25),
1024 kHttpResponsePartialContent);
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -07001025}
1026
1027TYPED_TEST(HttpFetcherTest, MultiHttpFetcherLengthLimitTest) {
Gilad Arnold9bedeb52011-11-17 16:19:57 -08001028 if (!this->test_.IsMulti())
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -07001029 return;
Gilad Arnold9bedeb52011-11-17 16:19:57 -08001030
1031 scoped_ptr<HttpServer> server(this->test_.CreateServer());
1032 ASSERT_TRUE(server->started_);
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -07001033
Andrew de los Reyes819fef22010-12-17 11:33:58 -08001034 vector<pair<off_t, off_t> > ranges;
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -07001035 ranges.push_back(make_pair(0, 24));
Gilad Arnold9bedeb52011-11-17 16:19:57 -08001036 MultiTest(this->test_.NewLargeFetcher(),
1037 this->test_.BigUrl(),
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -07001038 ranges,
1039 "abcdefghijabcdefghijabcd",
1040 24,
Gilad Arnolde4ad2502011-12-29 17:08:54 -08001041 kHttpResponsePartialContent);
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -07001042}
1043
1044TYPED_TEST(HttpFetcherTest, MultiHttpFetcherMultiEndTest) {
Gilad Arnold9bedeb52011-11-17 16:19:57 -08001045 if (!this->test_.IsMulti())
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -07001046 return;
Gilad Arnold9bedeb52011-11-17 16:19:57 -08001047
1048 scoped_ptr<HttpServer> server(this->test_.CreateServer());
1049 ASSERT_TRUE(server->started_);
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -07001050
Andrew de los Reyes819fef22010-12-17 11:33:58 -08001051 vector<pair<off_t, off_t> > ranges;
Gilad Arnolde4ad2502011-12-29 17:08:54 -08001052 ranges.push_back(make_pair(kBigLength - 2, 0));
1053 ranges.push_back(make_pair(kBigLength - 3, 0));
Gilad Arnold9bedeb52011-11-17 16:19:57 -08001054 MultiTest(this->test_.NewLargeFetcher(),
1055 this->test_.BigUrl(),
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -07001056 ranges,
1057 "ijhij",
1058 5,
Gilad Arnold9bedeb52011-11-17 16:19:57 -08001059 kHttpResponsePartialContent);
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -07001060}
1061
1062TYPED_TEST(HttpFetcherTest, MultiHttpFetcherInsufficientTest) {
Gilad Arnold9bedeb52011-11-17 16:19:57 -08001063 if (!this->test_.IsMulti())
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -07001064 return;
Gilad Arnold9bedeb52011-11-17 16:19:57 -08001065
1066 scoped_ptr<HttpServer> server(this->test_.CreateServer());
1067 ASSERT_TRUE(server->started_);
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -07001068
Andrew de los Reyes819fef22010-12-17 11:33:58 -08001069 vector<pair<off_t, off_t> > ranges;
Gilad Arnold9bedeb52011-11-17 16:19:57 -08001070 ranges.push_back(make_pair(kBigLength - 2, 4));
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -07001071 for (int i = 0; i < 2; ++i) {
Andrew de los Reyes819fef22010-12-17 11:33:58 -08001072 LOG(INFO) << "i = " << i;
Gilad Arnold9bedeb52011-11-17 16:19:57 -08001073 MultiTest(this->test_.NewLargeFetcher(),
1074 this->test_.BigUrl(),
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -07001075 ranges,
1076 "ij",
1077 2,
Gilad Arnold9bedeb52011-11-17 16:19:57 -08001078 kHttpResponseUndefined);
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -07001079 ranges.push_back(make_pair(0, 5));
1080 }
1081}
1082
Gilad Arnold9bedeb52011-11-17 16:19:57 -08001083// Issue #18143: when a fetch of a secondary chunk out of a chain, then it
1084// should retry with other proxies listed before giving up.
1085//
1086// (1) successful recovery: The offset fetch will fail twice but succeed with
1087// the third proxy.
1088TYPED_TEST(HttpFetcherTest, MultiHttpFetcherErrorIfOffsetRecoverableTest) {
1089 if (!this->test_.IsMulti())
1090 return;
1091
1092 scoped_ptr<HttpServer> server(this->test_.CreateServer());
1093 ASSERT_TRUE(server->started_);
1094
1095 vector<pair<off_t, off_t> > ranges;
1096 ranges.push_back(make_pair(0, 25));
Gilad Arnolde4ad2502011-12-29 17:08:54 -08001097 ranges.push_back(make_pair(99, 0));
Gilad Arnold9bedeb52011-11-17 16:19:57 -08001098 MultiTest(this->test_.NewLargeFetcher(3),
1099 LocalServerUrlForPath(base::StringPrintf("/error-if-offset/%d/2",
1100 kBigLength)),
1101 ranges,
1102 "abcdefghijabcdefghijabcdejabcdefghijabcdef",
1103 kBigLength - (99 - 25),
1104 kHttpResponsePartialContent);
1105}
1106
1107// (2) unsuccessful recovery: The offset fetch will fail repeatedly. The
1108// fetcher will signal a (failed) completed transfer to the delegate.
1109TYPED_TEST(HttpFetcherTest, MultiHttpFetcherErrorIfOffsetUnrecoverableTest) {
1110 if (!this->test_.IsMulti())
1111 return;
1112
1113 scoped_ptr<HttpServer> server(this->test_.CreateServer());
1114 ASSERT_TRUE(server->started_);
1115
1116 vector<pair<off_t, off_t> > ranges;
1117 ranges.push_back(make_pair(0, 25));
Gilad Arnolde4ad2502011-12-29 17:08:54 -08001118 ranges.push_back(make_pair(99, 0));
Gilad Arnold9bedeb52011-11-17 16:19:57 -08001119 MultiTest(this->test_.NewLargeFetcher(2),
1120 LocalServerUrlForPath(base::StringPrintf("/error-if-offset/%d/3",
1121 kBigLength)),
1122 ranges,
1123 "abcdefghijabcdefghijabcde", // only received the first chunk
1124 25,
1125 kHttpResponseUndefined);
1126}
1127
1128
1129
Andrew de los Reyesd57d1472010-10-21 13:34:08 -07001130namespace {
Darin Petkovfc7a0ce2010-10-25 10:38:37 -07001131class BlockedTransferTestDelegate : public HttpFetcherDelegate {
Andrew de los Reyesd57d1472010-10-21 13:34:08 -07001132 public:
1133 virtual void ReceivedBytes(HttpFetcher* fetcher,
1134 const char* bytes, int length) {
1135 ADD_FAILURE();
1136 }
1137 virtual void TransferComplete(HttpFetcher* fetcher, bool successful) {
1138 EXPECT_FALSE(successful);
1139 g_main_loop_quit(loop_);
1140 }
Darin Petkov9ce452b2010-11-17 14:33:28 -08001141 virtual void TransferTerminated(HttpFetcher* fetcher) {
1142 ADD_FAILURE();
1143 }
Andrew de los Reyesd57d1472010-10-21 13:34:08 -07001144 GMainLoop* loop_;
1145};
1146
1147} // namespace
1148
Darin Petkovfc7a0ce2010-10-25 10:38:37 -07001149TYPED_TEST(HttpFetcherTest, BlockedTransferTest) {
Gilad Arnold9bedeb52011-11-17 16:19:57 -08001150 if (this->test_.IsMock() || this->test_.IsMulti())
Andrew de los Reyesd57d1472010-10-21 13:34:08 -07001151 return;
Andrew de los Reyesd57d1472010-10-21 13:34:08 -07001152
Darin Petkovfc7a0ce2010-10-25 10:38:37 -07001153 for (int i = 0; i < 2; i++) {
Gilad Arnold9bedeb52011-11-17 16:19:57 -08001154 scoped_ptr<HttpServer> server(this->test_.CreateServer());
1155 ASSERT_TRUE(server->started_);
Andrew de los Reyesd57d1472010-10-21 13:34:08 -07001156
Darin Petkovfc7a0ce2010-10-25 10:38:37 -07001157 GMainLoop* loop = g_main_loop_new(g_main_context_default(), FALSE);
Jay Srinivasan135a58b2012-07-13 12:46:49 -07001158 {
1159 BlockedTransferTestDelegate delegate;
1160 delegate.loop_ = loop;
Andrew de los Reyesd57d1472010-10-21 13:34:08 -07001161
Jay Srinivasan135a58b2012-07-13 12:46:49 -07001162 bool is_allowed = (i != 0);
1163 scoped_ptr<HttpFetcher> fetcher(this->test_.NewLargeFetcher());
1164 MockConnectionManager* mock_cm = dynamic_cast<MockConnectionManager*>(
Jay Srinivasan6f6ea002012-12-14 11:26:28 -08001165 fetcher->GetSystemState()->connection_manager());
Jay Srinivasan135a58b2012-07-13 12:46:49 -07001166 EXPECT_CALL(*mock_cm, GetConnectionType(_,_))
1167 .WillRepeatedly(DoAll(SetArgumentPointee<1>(kNetWifi), Return(true)));
1168 EXPECT_CALL(*mock_cm, IsUpdateAllowedOver(kNetWifi))
1169 .WillRepeatedly(Return(is_allowed));
1170 EXPECT_CALL(*mock_cm, StringForConnectionType(kNetWifi))
1171 .WillRepeatedly(Return(flimflam::kTypeWifi));
Jay Srinivasan43488792012-06-19 00:25:31 -07001172
Jay Srinivasan135a58b2012-07-13 12:46:49 -07001173 bool is_official_build = (i == 1);
1174 LOG(INFO) << "is_update_allowed_over_connection: " << is_allowed;
1175 LOG(INFO) << "is_official_build: " << is_official_build;
1176 fetcher->SetBuildType(is_official_build);
1177 fetcher->set_delegate(&delegate);
Darin Petkovfc7a0ce2010-10-25 10:38:37 -07001178
Jay Srinivasan135a58b2012-07-13 12:46:49 -07001179 StartTransferArgs start_xfer_args =
1180 { fetcher.get(), LocalServerUrlForPath(this->test_.SmallUrl()) };
Darin Petkovfc7a0ce2010-10-25 10:38:37 -07001181
Jay Srinivasan135a58b2012-07-13 12:46:49 -07001182 g_timeout_add(0, StartTransfer, &start_xfer_args);
1183 g_main_loop_run(loop);
1184 }
Darin Petkovfc7a0ce2010-10-25 10:38:37 -07001185 g_main_loop_unref(loop);
1186 }
Andrew de los Reyesd57d1472010-10-21 13:34:08 -07001187}
1188
rspangler@google.com49fdf182009-10-10 00:57:34 +00001189} // namespace chromeos_update_engine