Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(94)

Side by Side Diff: src/platform/update_engine/http_fetcher_unittest.cc

Issue 466036: AU: Beginnings of delta support (Closed)
Patch Set: Created 11 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2009 The Chromium OS Authors. All rights reserved. 1 // Copyright (c) 2009 The Chromium OS Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include <unistd.h> 5 #include <unistd.h>
6 #include <string>
7 #include <vector>
6 #include <base/scoped_ptr.h> 8 #include <base/scoped_ptr.h>
7 #include <glib.h> 9 #include <glib.h>
8 #include <base/logging.h>
9 #include <gtest/gtest.h> 10 #include <gtest/gtest.h>
11 #include "chromeos/obsolete_logging.h"
10 #include "update_engine/libcurl_http_fetcher.h" 12 #include "update_engine/libcurl_http_fetcher.h"
11 #include "update_engine/mock_http_fetcher.h" 13 #include "update_engine/mock_http_fetcher.h"
12 14
15 using std::string;
16 using std::vector;
17
13 namespace chromeos_update_engine { 18 namespace chromeos_update_engine {
14 19
15 namespace { 20 namespace {
16 // WARNING, if you update this, you must also update test_http_server.py 21 // WARNING, if you update this, you must also update test_http_server.py
17 const char* const kServerPort = "8080"; 22 const char* const kServerPort = "8080";
18 string LocalServerUrlForPath(const string& path) { 23 string LocalServerUrlForPath(const string& path) {
19 return string("http://127.0.0.1:") + kServerPort + path; 24 return string("http://127.0.0.1:") + kServerPort + path;
20 } 25 }
21 } 26 }
22 27
23 template <typename T> 28 template <typename T>
24 class HttpFetcherTest : public ::testing::Test { 29 class HttpFetcherTest : public ::testing::Test {
25 public: 30 public:
26 HttpFetcher* NewLargeFetcher() = 0; 31 HttpFetcher* NewLargeFetcher() = 0;
27 HttpFetcher* NewSmallFetcher() = 0; 32 HttpFetcher* NewSmallFetcher() = 0;
28 string BigUrl() const = 0; 33 string BigUrl() const = 0;
29 string SmallUrl() const = 0; 34 string SmallUrl() const = 0;
35 bool IsMock() const = 0;
30 }; 36 };
31 37
32 class NullHttpServer { 38 class NullHttpServer {
33 public: 39 public:
34 NullHttpServer() : started_(true) {} 40 NullHttpServer() : started_(true) {}
35 ~NullHttpServer() {} 41 ~NullHttpServer() {}
36 bool started_; 42 bool started_;
37 }; 43 };
38 44
39 45
40 template <> 46 template <>
41 class HttpFetcherTest<MockHttpFetcher> : public ::testing::Test { 47 class HttpFetcherTest<MockHttpFetcher> : public ::testing::Test {
42 public: 48 public:
43 HttpFetcher* NewLargeFetcher() { 49 HttpFetcher* NewLargeFetcher() {
44 vector<char> big_data(1000000); 50 vector<char> big_data(1000000);
45 return new MockHttpFetcher(big_data.data(), big_data.size()); 51 return new MockHttpFetcher(big_data.data(), big_data.size());
46 } 52 }
47 HttpFetcher* NewSmallFetcher() { 53 HttpFetcher* NewSmallFetcher() {
48 return new MockHttpFetcher("x", 1); 54 return new MockHttpFetcher("x", 1);
49 } 55 }
50 string BigUrl() const { 56 string BigUrl() const {
51 return "unused://unused"; 57 return "unused://unused";
52 } 58 }
53 string SmallUrl() const { 59 string SmallUrl() const {
54 return "unused://unused"; 60 return "unused://unused";
55 } 61 }
62 bool IsMock() const { return true; }
56 typedef NullHttpServer HttpServer; 63 typedef NullHttpServer HttpServer;
57 }; 64 };
58 65
59 class PythonHttpServer { 66 class PythonHttpServer {
60 public: 67 public:
61 PythonHttpServer() { 68 PythonHttpServer() {
62 char *argv[2] = {strdup("./test_http_server.py"), NULL}; 69 char *argv[2] = {strdup("./test_http_server"), NULL};
63 GError *err; 70 GError *err;
64 started_ = false; 71 started_ = false;
65 if (!g_spawn_async(NULL, 72 if (!g_spawn_async(NULL,
66 argv, 73 argv,
67 NULL, 74 NULL,
68 G_SPAWN_DO_NOT_REAP_CHILD, 75 G_SPAWN_DO_NOT_REAP_CHILD,
69 NULL, 76 NULL,
70 NULL, 77 NULL,
71 &pid_, 78 &pid_,
72 &err)) { 79 &err)) {
73 return; 80 return;
74 } 81 }
75 int rc = 1; 82 int rc = 1;
76 while (0 != rc) { 83 while (0 != rc) {
77
78 rc = system((string("wget --output-document=/dev/null ") + 84 rc = system((string("wget --output-document=/dev/null ") +
79 LocalServerUrlForPath("/test")).c_str()); 85 LocalServerUrlForPath("/test")).c_str());
80 usleep(10 * 1000); // 10 ms 86 usleep(10 * 1000); // 10 ms
81 } 87 }
82 started_ = true; 88 started_ = true;
83 free(argv[0]); 89 free(argv[0]);
84 return; 90 return;
85 } 91 }
86 ~PythonHttpServer() { 92 ~PythonHttpServer() {
87 if (!started_) 93 if (!started_)
(...skipping 17 matching lines...) Expand all
105 } 111 }
106 HttpFetcher* NewSmallFetcher() { 112 HttpFetcher* NewSmallFetcher() {
107 return NewLargeFetcher(); 113 return NewLargeFetcher();
108 } 114 }
109 string BigUrl() const { 115 string BigUrl() const {
110 return LocalServerUrlForPath("/big"); 116 return LocalServerUrlForPath("/big");
111 } 117 }
112 string SmallUrl() const { 118 string SmallUrl() const {
113 return LocalServerUrlForPath("/foo"); 119 return LocalServerUrlForPath("/foo");
114 } 120 }
121 bool IsMock() const { return false; }
115 typedef PythonHttpServer HttpServer; 122 typedef PythonHttpServer HttpServer;
116 }; 123 };
117 124
118 typedef ::testing::Types<LibcurlHttpFetcher, MockHttpFetcher> 125 typedef ::testing::Types<LibcurlHttpFetcher, MockHttpFetcher>
119 HttpFetcherTestTypes; 126 HttpFetcherTestTypes;
120 TYPED_TEST_CASE(HttpFetcherTest, HttpFetcherTestTypes); 127 TYPED_TEST_CASE(HttpFetcherTest, HttpFetcherTestTypes);
121 128
122 namespace { 129 namespace {
123 class HttpFetcherTestDelegate : public HttpFetcherDelegate { 130 class HttpFetcherTestDelegate : public HttpFetcherDelegate {
124 public: 131 public:
125 virtual void ReceivedBytes(HttpFetcher* fetcher, 132 virtual void ReceivedBytes(HttpFetcher* fetcher,
126 const char* bytes, int length) { 133 const char* bytes, int length) {
127 char str[length + 1]; 134 char str[length + 1];
128 memset(str, 0, length + 1); 135 memset(str, 0, length + 1);
129 memcpy(str, bytes, length); 136 memcpy(str, bytes, length);
130 } 137 }
131 virtual void TransferComplete(HttpFetcher* fetcher, bool successful) { 138 virtual void TransferComplete(HttpFetcher* fetcher, bool successful) {
132 g_main_loop_quit(loop_); 139 g_main_loop_quit(loop_);
133 } 140 }
134 GMainLoop* loop_; 141 GMainLoop* loop_;
135 }; 142 };
143
144 struct StartTransferArgs {
145 HttpFetcher *http_fetcher;
146 string url;
147 };
148
149 gboolean StartTransfer(gpointer data) {
150 StartTransferArgs *args = reinterpret_cast<StartTransferArgs*>(data);
151 args->http_fetcher->BeginTransfer(args->url);
152 return FALSE;
153 }
136 } // namespace {} 154 } // namespace {}
137 155
138 TYPED_TEST(HttpFetcherTest, SimpleTest) { 156 TYPED_TEST(HttpFetcherTest, SimpleTest) {
139 GMainLoop *loop = g_main_loop_new(g_main_context_default(), FALSE); 157 GMainLoop *loop = g_main_loop_new(g_main_context_default(), FALSE);
140 { 158 {
141 HttpFetcherTestDelegate delegate; 159 HttpFetcherTestDelegate delegate;
142 delegate.loop_ = loop; 160 delegate.loop_ = loop;
143 scoped_ptr<HttpFetcher> fetcher(this->NewSmallFetcher()); 161 scoped_ptr<HttpFetcher> fetcher(this->NewSmallFetcher());
144 fetcher->set_delegate(&delegate); 162 fetcher->set_delegate(&delegate);
145 163
146 typename TestFixture::HttpServer server; 164 typename TestFixture::HttpServer server;
147 ASSERT_TRUE(server.started_); 165 ASSERT_TRUE(server.started_);
148 166
149 fetcher->BeginTransfer(this->SmallUrl()); 167 StartTransferArgs start_xfer_args = {fetcher.get(), this->SmallUrl()};
168
169 g_timeout_add(0, StartTransfer, &start_xfer_args);
150 g_main_loop_run(loop); 170 g_main_loop_run(loop);
151 } 171 }
152 g_main_loop_unref(loop); 172 g_main_loop_unref(loop);
153 } 173 }
154 174
155 namespace { 175 namespace {
156 class PausingHttpFetcherTestDelegate : public HttpFetcherDelegate { 176 class PausingHttpFetcherTestDelegate : public HttpFetcherDelegate {
157 public: 177 public:
158 virtual void ReceivedBytes(HttpFetcher* fetcher, 178 virtual void ReceivedBytes(HttpFetcher* fetcher,
159 const char* bytes, int length) { 179 const char* bytes, int length) {
160 char str[length + 1]; 180 char str[length + 1];
161 LOG(INFO) << "got " << length << " bytes";
162 memset(str, 0, length + 1); 181 memset(str, 0, length + 1);
163 memcpy(str, bytes, length); 182 memcpy(str, bytes, length);
164 CHECK(!paused_); 183 CHECK(!paused_);
165 paused_ = true; 184 paused_ = true;
166 fetcher->Pause(); 185 fetcher->Pause();
167 LOG(INFO) << "calling pause";
168 } 186 }
169 virtual void TransferComplete(HttpFetcher* fetcher, bool successful) { 187 virtual void TransferComplete(HttpFetcher* fetcher, bool successful) {
170 g_main_loop_quit(loop_); 188 g_main_loop_quit(loop_);
171 } 189 }
172 void Unpause() { 190 void Unpause() {
173 CHECK(paused_); 191 CHECK(paused_);
174 paused_ = false; 192 paused_ = false;
175 fetcher_->Unpause(); 193 fetcher_->Unpause();
176 LOG(INFO) << "calling unpause";
177 } 194 }
178 bool paused_; 195 bool paused_;
179 HttpFetcher* fetcher_; 196 HttpFetcher* fetcher_;
180 GMainLoop* loop_; 197 GMainLoop* loop_;
181 }; 198 };
182 199
183 gboolean UnpausingTimeoutCallback(gpointer data) { 200 gboolean UnpausingTimeoutCallback(gpointer data) {
184 PausingHttpFetcherTestDelegate *delegate = 201 PausingHttpFetcherTestDelegate *delegate =
185 reinterpret_cast<PausingHttpFetcherTestDelegate*>(data); 202 reinterpret_cast<PausingHttpFetcherTestDelegate*>(data);
186 if (delegate->paused_) 203 if (delegate->paused_)
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
267 NULL); 284 NULL);
268 g_source_attach(timeout_source_, NULL); 285 g_source_attach(timeout_source_, NULL);
269 fetcher->BeginTransfer(this->BigUrl()); 286 fetcher->BeginTransfer(this->BigUrl());
270 287
271 g_main_loop_run(loop); 288 g_main_loop_run(loop);
272 g_source_destroy(timeout_source_); 289 g_source_destroy(timeout_source_);
273 } 290 }
274 g_main_loop_unref(loop); 291 g_main_loop_unref(loop);
275 } 292 }
276 293
294 namespace {
295 class FlakyHttpFetcherTestDelegate : public HttpFetcherDelegate {
296 public:
297 virtual void ReceivedBytes(HttpFetcher* fetcher,
298 const char* bytes, int length) {
299 data.append(bytes, length);
300 }
301 virtual void TransferComplete(HttpFetcher* fetcher, bool successful) {
302 g_main_loop_quit(loop_);
303 }
304 string data;
305 GMainLoop* loop_;
306 };
307 } // namespace {}
308
309 TYPED_TEST(HttpFetcherTest, FlakyTest) {
310 if (this->IsMock())
311 return;
312 GMainLoop *loop = g_main_loop_new(g_main_context_default(), FALSE);
313 {
314 FlakyHttpFetcherTestDelegate delegate;
315 delegate.loop_ = loop;
316 scoped_ptr<HttpFetcher> fetcher(this->NewSmallFetcher());
317 fetcher->set_delegate(&delegate);
318
319 typename TestFixture::HttpServer server;
320 ASSERT_TRUE(server.started_);
321
322 StartTransferArgs start_xfer_args = {
323 fetcher.get(),
324 LocalServerUrlForPath("/flaky")
325 };
326
327 g_timeout_add(0, StartTransfer, &start_xfer_args);
328 g_main_loop_run(loop);
329
330 // verify the data we get back
331 ASSERT_EQ(100000, delegate.data.size());
332 for (int i = 0; i < 100000; i += 10) {
333 // Assert so that we don't flood the screen w/ EXPECT errors on failure.
334 ASSERT_EQ(delegate.data.substr(i, 10), "abcdefghij");
335 }
336 }
337 g_main_loop_unref(loop);
338 }
339
277 } // namespace chromeos_update_engine 340 } // namespace chromeos_update_engine
OLDNEW
« no previous file with comments | « src/platform/update_engine/http_fetcher.h ('k') | src/platform/update_engine/libcurl_http_fetcher.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698