blob: a46ad2c33898b20e8c6d1e08182995dbe85e71a3 [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>
Jay Srinivasan43488792012-06-19 00:25:31 -070015#include <chromeos/dbus/service_constants.h>
Andrew de los Reyes45168102010-11-22 11:13:50 -080016#include <glib.h>
17#include <gtest/gtest.h>
18
Gilad Arnold9bedeb52011-11-17 16:19:57 -080019#include "update_engine/http_common.h"
20#include "update_engine/http_fetcher_unittest.h"
rspangler@google.com49fdf182009-10-10 00:57:34 +000021#include "update_engine/libcurl_http_fetcher.h"
Jay Srinivasan43488792012-06-19 00:25:31 -070022#include "update_engine/mock_connection_manager.h"
rspangler@google.com49fdf182009-10-10 00:57:34 +000023#include "update_engine/mock_http_fetcher.h"
Jay Srinivasan08fce042012-06-07 16:31:01 -070024#include "update_engine/mock_system_state.h"
Andrew de los Reyes819fef22010-12-17 11:33:58 -080025#include "update_engine/multi_range_http_fetcher.h"
Andrew de los Reyes45168102010-11-22 11:13:50 -080026#include "update_engine/proxy_resolver.h"
Jay Srinivasan08fce042012-06-07 16:31:01 -070027#include "update_engine/utils.h"
rspangler@google.com49fdf182009-10-10 00:57:34 +000028
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -070029using std::make_pair;
Andrew de los Reyes819fef22010-12-17 11:33:58 -080030using std::pair;
adlr@google.comc98a7ed2009-12-04 18:54:03 +000031using std::string;
32using std::vector;
33
Jay Srinivasan43488792012-06-19 00:25:31 -070034using testing::_;
35using testing::SetArgumentPointee;
36using testing::DoAll;
37using testing::Return;
38
Gilad Arnold9bedeb52011-11-17 16:19:57 -080039namespace {
40
41const int kBigLength = 100000;
42const int kMediumLength = 1000;
Gilad Arnold34bf1ee2012-02-09 16:16:02 -080043const int kFlakyTruncateLength = 29000;
44const int kFlakySleepEvery = 3;
Gilad Arnold9bedeb52011-11-17 16:19:57 -080045const int kFlakySleepSecs = 10;
46
47} // namespace
48
rspangler@google.com49fdf182009-10-10 00:57:34 +000049namespace chromeos_update_engine {
50
Gilad Arnold9bedeb52011-11-17 16:19:57 -080051static const char *kUnusedUrl = "unused://unused";
52
53static inline string LocalServerUrlForPath(const string& path) {
Jay Srinivasan43488792012-06-19 00:25:31 -070054 return base::StringPrintf("http://127.0.0.1:%d%s", kServerPort, path.c_str());
rspangler@google.com49fdf182009-10-10 00:57:34 +000055}
56
Gilad Arnold9bedeb52011-11-17 16:19:57 -080057//
58// Class hierarchy for HTTP server implementations.
59//
60
61class HttpServer {
rspangler@google.com49fdf182009-10-10 00:57:34 +000062 public:
Gilad Arnold9bedeb52011-11-17 16:19:57 -080063 // This makes it an abstract class (dirty but works).
64 virtual ~HttpServer() = 0;
65
rspangler@google.com49fdf182009-10-10 00:57:34 +000066 bool started_;
67};
68
Gilad Arnold9bedeb52011-11-17 16:19:57 -080069HttpServer::~HttpServer() {}
rspangler@google.com49fdf182009-10-10 00:57:34 +000070
Gilad Arnold9bedeb52011-11-17 16:19:57 -080071
72class NullHttpServer : public HttpServer {
rspangler@google.com49fdf182009-10-10 00:57:34 +000073 public:
Gilad Arnold9bedeb52011-11-17 16:19:57 -080074 NullHttpServer() {
75 started_ = true;
rspangler@google.com49fdf182009-10-10 00:57:34 +000076 }
rspangler@google.com49fdf182009-10-10 00:57:34 +000077};
78
Gilad Arnold9bedeb52011-11-17 16:19:57 -080079
80class PythonHttpServer : public HttpServer {
rspangler@google.com49fdf182009-10-10 00:57:34 +000081 public:
82 PythonHttpServer() {
adlr@google.comc98a7ed2009-12-04 18:54:03 +000083 char *argv[2] = {strdup("./test_http_server"), NULL};
rspangler@google.com49fdf182009-10-10 00:57:34 +000084 GError *err;
85 started_ = false;
Andrew de los Reyes08c4e272010-04-15 14:02:17 -070086 validate_quit_ = true;
rspangler@google.com49fdf182009-10-10 00:57:34 +000087 if (!g_spawn_async(NULL,
88 argv,
89 NULL,
90 G_SPAWN_DO_NOT_REAP_CHILD,
91 NULL,
92 NULL,
93 &pid_,
94 &err)) {
Jay Srinivasan135a58b2012-07-13 12:46:49 -070095 LOG(INFO) << "unable to spawn http server process";
rspangler@google.com49fdf182009-10-10 00:57:34 +000096 return;
97 }
Jay Srinivasan135a58b2012-07-13 12:46:49 -070098 LOG(INFO) << "started http server with pid " << pid_;
rspangler@google.com49fdf182009-10-10 00:57:34 +000099 int rc = 1;
Andrew de los Reyese7dcc2a2011-08-19 10:50:37 -0700100 const uint64_t kMaxSleep = 60UL * 60UL * 1000UL * 1000UL; // 60 min
101 uint64_t timeout = 15 * 1000; // 15 ms
Andrew de los Reyes3270f742010-07-15 22:28:14 -0700102 started_ = true;
Jay Srinivasan135a58b2012-07-13 12:46:49 -0700103 while (rc && timeout < kMaxSleep) {
104 // Wait before the first attempt also as it takes a while for the
105 // test_http_server to be ready.
106 LOG(INFO) << "waiting for " << timeout / 1000 << " ms";
107 if (timeout < (1000 * 1000)) // sub 1-second sleep, use usleep
108 usleep(static_cast<useconds_t>(timeout));
109 else
110 sleep(static_cast<unsigned int>(timeout / (1000 * 1000)));
111 timeout *= 2;
112
Andrew de los Reyes3270f742010-07-15 22:28:14 -0700113 LOG(INFO) << "running wget to start";
Jay Srinivasan135a58b2012-07-13 12:46:49 -0700114 // rc should be 0 if we're able to successfully talk to the server.
rspangler@google.com49fdf182009-10-10 00:57:34 +0000115 rc = system((string("wget --output-document=/dev/null ") +
116 LocalServerUrlForPath("/test")).c_str());
Jay Srinivasan135a58b2012-07-13 12:46:49 -0700117 LOG(INFO) << "done running wget to start, rc = " << rc;
rspangler@google.com49fdf182009-10-10 00:57:34 +0000118 }
Jay Srinivasan135a58b2012-07-13 12:46:49 -0700119
120 if (rc) {
121 LOG(ERROR) << "Http server is not responding to wget.";
122 // TODO(jaysri): Currently we're overloading two things in
123 // started_ flag. One is that the process is running and other
124 // is that the process is responsive. We should separate these
125 // two so that we can do cleanup appropriately in each case.
126 started_ = false;
127 }
128
rspangler@google.com49fdf182009-10-10 00:57:34 +0000129 free(argv[0]);
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -0700130 LOG(INFO) << "gdb attach now!";
rspangler@google.com49fdf182009-10-10 00:57:34 +0000131 }
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800132
rspangler@google.com49fdf182009-10-10 00:57:34 +0000133 ~PythonHttpServer() {
Jay Srinivasan135a58b2012-07-13 12:46:49 -0700134 if (!started_) {
135 LOG(INFO) << "not waiting for http server with pid " << pid_
136 << " to terminate, as it's not responding.";
137 // TODO(jaysri): Kill the process if it's really running but
138 // wgets or failing for some reason. Or if it's not running,
139 // add code to get rid of the defunct process.
rspangler@google.com49fdf182009-10-10 00:57:34 +0000140 return;
Jay Srinivasan135a58b2012-07-13 12:46:49 -0700141 }
142
rspangler@google.com49fdf182009-10-10 00:57:34 +0000143 // request that the server exit itself
Andrew de los Reyes3270f742010-07-15 22:28:14 -0700144 LOG(INFO) << "running wget to exit";
Andrew de los Reyes08c4e272010-04-15 14:02:17 -0700145 int rc = system((string("wget -t 1 --output-document=/dev/null ") +
Andrew de los Reyes9bbd1872010-07-16 14:52:29 -0700146 LocalServerUrlForPath("/quitquitquit")).c_str());
Andrew de los Reyes3270f742010-07-15 22:28:14 -0700147 LOG(INFO) << "done running wget to exit";
Andrew de los Reyes08c4e272010-04-15 14:02:17 -0700148 if (validate_quit_)
149 EXPECT_EQ(0, rc);
Jay Srinivasan135a58b2012-07-13 12:46:49 -0700150 LOG(INFO) << "waiting for http server with pid " << pid_ << " to terminate";
151 int status;
152 waitpid(pid_, &status, 0);
153 LOG(INFO) << "http server with pid " << pid_
154 << " terminated with status " << status;
rspangler@google.com49fdf182009-10-10 00:57:34 +0000155 }
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800156
rspangler@google.com49fdf182009-10-10 00:57:34 +0000157 GPid pid_;
Andrew de los Reyes08c4e272010-04-15 14:02:17 -0700158 bool validate_quit_;
rspangler@google.com49fdf182009-10-10 00:57:34 +0000159};
160
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800161//
162// Class hierarchy for HTTP fetcher test wrappers.
163//
164
165class AnyHttpFetcherTest {
rspangler@google.com49fdf182009-10-10 00:57:34 +0000166 public:
Jay Srinivasan43488792012-06-19 00:25:31 -0700167 AnyHttpFetcherTest()
168 : mock_connection_manager_(&mock_system_state_) {
169 mock_system_state_.SetConnectionManager(&mock_connection_manager_);
170 }
171
172 virtual HttpFetcher* NewLargeFetcher(size_t num_proxies) = 0;
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800173 HttpFetcher* NewLargeFetcher() {
174 return NewLargeFetcher(1);
175 }
176
177 virtual HttpFetcher* NewSmallFetcher(size_t num_proxies) = 0;
178 HttpFetcher* NewSmallFetcher() {
179 return NewSmallFetcher(1);
180 }
181
182 virtual string BigUrl() const { return kUnusedUrl; }
183 virtual string SmallUrl() const { return kUnusedUrl; }
184 virtual string ErrorUrl() const { return kUnusedUrl; }
185
186 virtual bool IsMock() const = 0;
187 virtual bool IsMulti() const = 0;
188
189 virtual void IgnoreServerAborting(HttpServer* server) const {}
190
191 virtual HttpServer *CreateServer() = 0;
192
193 protected:
194 DirectProxyResolver proxy_resolver_;
Jay Srinivasan43488792012-06-19 00:25:31 -0700195 MockSystemState mock_system_state_;
196 MockConnectionManager mock_connection_manager_;
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800197};
198
199class MockHttpFetcherTest : public AnyHttpFetcherTest {
200 public:
201 // Necessary to unhide the definition in the base class.
202 using AnyHttpFetcherTest::NewLargeFetcher;
203 virtual HttpFetcher* NewLargeFetcher(size_t num_proxies) {
204 vector<char> big_data(1000000);
205 CHECK(num_proxies > 0);
206 proxy_resolver_.set_num_proxies(num_proxies);
207 return new MockHttpFetcher(
208 big_data.data(),
209 big_data.size(),
210 reinterpret_cast<ProxyResolver*>(&proxy_resolver_));
211 }
212
213 // Necessary to unhide the definition in the base class.
214 using AnyHttpFetcherTest::NewSmallFetcher;
215 virtual HttpFetcher* NewSmallFetcher(size_t num_proxies) {
216 CHECK(num_proxies > 0);
217 proxy_resolver_.set_num_proxies(num_proxies);
218 return new MockHttpFetcher(
219 "x",
220 1,
221 reinterpret_cast<ProxyResolver*>(&proxy_resolver_));
222 }
223
224 virtual bool IsMock() const { return true; }
225 virtual bool IsMulti() const { return false; }
226
227 virtual HttpServer *CreateServer() {
228 return new NullHttpServer;
229 }
230};
231
232class LibcurlHttpFetcherTest : public AnyHttpFetcherTest {
233 public:
234 // Necessary to unhide the definition in the base class.
235 using AnyHttpFetcherTest::NewLargeFetcher;
236 virtual HttpFetcher* NewLargeFetcher(size_t num_proxies) {
237 CHECK(num_proxies > 0);
238 proxy_resolver_.set_num_proxies(num_proxies);
Andrew de los Reyes45168102010-11-22 11:13:50 -0800239 LibcurlHttpFetcher *ret = new
Jay Srinivasan08fce042012-06-07 16:31:01 -0700240 LibcurlHttpFetcher(reinterpret_cast<ProxyResolver*>(&proxy_resolver_),
241 &mock_system_state_);
Darin Petkovb83371f2010-08-17 09:34:49 -0700242 // Speed up test execution.
243 ret->set_idle_seconds(1);
244 ret->set_retry_seconds(1);
Darin Petkovfc7a0ce2010-10-25 10:38:37 -0700245 ret->SetBuildType(false);
rspangler@google.com49fdf182009-10-10 00:57:34 +0000246 return ret;
247 }
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800248
249 // Necessary to unhide the definition in the base class.
250 using AnyHttpFetcherTest::NewSmallFetcher;
251 virtual HttpFetcher* NewSmallFetcher(size_t num_proxies) {
252 return NewLargeFetcher(num_proxies);
rspangler@google.com49fdf182009-10-10 00:57:34 +0000253 }
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800254
255 virtual string BigUrl() const {
256 return LocalServerUrlForPath(base::StringPrintf("/download/%d",
257 kBigLength));
rspangler@google.com49fdf182009-10-10 00:57:34 +0000258 }
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800259 virtual string SmallUrl() const {
rspangler@google.com49fdf182009-10-10 00:57:34 +0000260 return LocalServerUrlForPath("/foo");
261 }
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800262 virtual string ErrorUrl() const {
Gilad Arnold48085ba2011-11-16 09:36:08 -0800263 return LocalServerUrlForPath("/error");
264 }
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800265
266 virtual bool IsMock() const { return false; }
267 virtual bool IsMulti() const { return false; }
268
269 virtual void IgnoreServerAborting(HttpServer* server) const {
Andrew de los Reyes08c4e272010-04-15 14:02:17 -0700270 PythonHttpServer *pyserver = reinterpret_cast<PythonHttpServer*>(server);
271 pyserver->validate_quit_ = false;
272 }
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800273
274 virtual HttpServer *CreateServer() {
275 return new PythonHttpServer;
276 }
rspangler@google.com49fdf182009-10-10 00:57:34 +0000277};
278
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800279class MultiRangeHttpFetcherTest : public LibcurlHttpFetcherTest {
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -0700280 public:
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800281 // Necessary to unhide the definition in the base class.
282 using AnyHttpFetcherTest::NewLargeFetcher;
283 virtual HttpFetcher* NewLargeFetcher(size_t num_proxies) {
284 CHECK(num_proxies > 0);
285 proxy_resolver_.set_num_proxies(num_proxies);
Andrew de los Reyes819fef22010-12-17 11:33:58 -0800286 ProxyResolver* resolver =
287 reinterpret_cast<ProxyResolver*>(&proxy_resolver_);
Jay Srinivasan08fce042012-06-07 16:31:01 -0700288 MultiRangeHttpFetcher *ret = new MultiRangeHttpFetcher(
289 new LibcurlHttpFetcher(resolver, &mock_system_state_));
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*>(
400 fetcher->GetSystemState()->GetConnectionManager());
401 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*>(
428 fetcher->GetSystemState()->GetConnectionManager());
429 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*>(
464 fetcher->GetSystemState()->GetConnectionManager());
465 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*>(
543 fetcher->GetSystemState()->GetConnectionManager());
544 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*>(
619 delegate.fetcher_->GetSystemState()->GetConnectionManager());
620 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*>(
677 fetcher->GetSystemState()->GetConnectionManager());
678 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*>(
759 fetcher->GetSystemState()->GetConnectionManager());
760 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*>(
851 fetcher->GetSystemState()->GetConnectionManager());
852 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*>(
969 fetcher_in->GetSystemState()->GetConnectionManager());
970 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*>(
1165 fetcher->GetSystemState()->GetConnectionManager());
1166 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