| Index: http_fetcher_unittest.cc
|
| diff --git a/http_fetcher_unittest.cc b/http_fetcher_unittest.cc
|
| index d0962677224fec039016f1a05335a416fb26e2aa..06cabacc15ce5f3a16d31741322361d3962f5d9f 100644
|
| --- a/http_fetcher_unittest.cc
|
| +++ b/http_fetcher_unittest.cc
|
| @@ -5,6 +5,7 @@
|
| #include <unistd.h>
|
|
|
| #include <string>
|
| +#include <utility>
|
| #include <vector>
|
|
|
| #include "base/logging.h"
|
| @@ -14,15 +15,18 @@
|
| #include "gtest/gtest.h"
|
| #include "update_engine/libcurl_http_fetcher.h"
|
| #include "update_engine/mock_http_fetcher.h"
|
| +#include "update_engine/multi_http_fetcher.h"
|
|
|
| +using std::make_pair;
|
| using std::string;
|
| using std::vector;
|
|
|
| namespace chromeos_update_engine {
|
|
|
| namespace {
|
| -// WARNING, if you update this, you must also update test_http_server.py
|
| +// WARNING, if you update these, you must also update test_http_server.py
|
| const char* const kServerPort = "8080";
|
| +const int kBigSize = 100000;
|
| string LocalServerUrlForPath(const string& path) {
|
| return string("http://127.0.0.1:") + kServerPort + path;
|
| }
|
| @@ -36,6 +40,7 @@ class HttpFetcherTest : public ::testing::Test {
|
| string BigUrl() const = 0;
|
| string SmallUrl() const = 0;
|
| bool IsMock() const = 0;
|
| + bool IsMulti() const = 0;
|
| };
|
|
|
| class NullHttpServer {
|
| @@ -63,6 +68,7 @@ class HttpFetcherTest<MockHttpFetcher> : public ::testing::Test {
|
| return "unused://unused";
|
| }
|
| bool IsMock() const { return true; }
|
| + bool IsMulti() const { return false; }
|
| typedef NullHttpServer HttpServer;
|
| void IgnoreServerAborting(HttpServer* server) const {}
|
| };
|
| @@ -101,6 +107,7 @@ class PythonHttpServer {
|
| }
|
| }
|
| free(argv[0]);
|
| + LOG(INFO) << "gdb attach now!";
|
| return;
|
| }
|
| ~PythonHttpServer() {
|
| @@ -123,7 +130,7 @@ class PythonHttpServer {
|
| template <>
|
| class HttpFetcherTest<LibcurlHttpFetcher> : public ::testing::Test {
|
| public:
|
| - HttpFetcher* NewLargeFetcher() {
|
| + virtual HttpFetcher* NewLargeFetcher() {
|
| LibcurlHttpFetcher *ret = new LibcurlHttpFetcher;
|
| // Speed up test execution.
|
| ret->set_idle_seconds(1);
|
| @@ -140,6 +147,7 @@ class HttpFetcherTest<LibcurlHttpFetcher> : public ::testing::Test {
|
| return LocalServerUrlForPath("/foo");
|
| }
|
| bool IsMock() const { return false; }
|
| + bool IsMulti() const { return false; }
|
| typedef PythonHttpServer HttpServer;
|
| void IgnoreServerAborting(HttpServer* server) const {
|
| PythonHttpServer *pyserver = reinterpret_cast<PythonHttpServer*>(server);
|
| @@ -147,8 +155,28 @@ class HttpFetcherTest<LibcurlHttpFetcher> : public ::testing::Test {
|
| }
|
| };
|
|
|
| -typedef ::testing::Types<LibcurlHttpFetcher, MockHttpFetcher>
|
| - HttpFetcherTestTypes;
|
| +template <>
|
| +class HttpFetcherTest<MultiHttpFetcher<LibcurlHttpFetcher> >
|
| + : public HttpFetcherTest<LibcurlHttpFetcher> {
|
| + public:
|
| + HttpFetcher* NewLargeFetcher() {
|
| + MultiHttpFetcher<LibcurlHttpFetcher> *ret =
|
| + new MultiHttpFetcher<LibcurlHttpFetcher>;
|
| + MultiHttpFetcher<LibcurlHttpFetcher>::RangesVect
|
| + ranges(1, make_pair(0, -1));
|
| + ret->set_ranges(ranges);
|
| + // Speed up test execution.
|
| + ret->set_idle_seconds(1);
|
| + ret->set_retry_seconds(1);
|
| + return ret;
|
| + }
|
| + bool IsMulti() const { return true; }
|
| +};
|
| +
|
| +typedef ::testing::Types<LibcurlHttpFetcher,
|
| + MockHttpFetcher,
|
| + MultiHttpFetcher<LibcurlHttpFetcher> >
|
| +HttpFetcherTestTypes;
|
| TYPED_TEST_CASE(HttpFetcherTest, HttpFetcherTestTypes);
|
|
|
| namespace {
|
| @@ -333,7 +361,6 @@ TYPED_TEST(HttpFetcherTest, AbortTest) {
|
|
|
| g_main_loop_run(loop);
|
| g_source_destroy(timeout_source_);
|
| - EXPECT_EQ(0, fetcher->http_response_code());
|
| }
|
| g_main_loop_unref(loop);
|
| }
|
| @@ -550,4 +577,123 @@ TYPED_TEST(HttpFetcherTest, BeyondMaxRedirectTest) {
|
| RedirectTest(false, url, this->NewLargeFetcher());
|
| }
|
|
|
| +namespace {
|
| +class MultiHttpFetcherTestDelegate : public HttpFetcherDelegate {
|
| + public:
|
| + MultiHttpFetcherTestDelegate(int expected_response_code)
|
| + : expected_response_code_(expected_response_code) {}
|
| + virtual void ReceivedBytes(HttpFetcher* fetcher,
|
| + const char* bytes, int length) {
|
| + data.append(bytes, length);
|
| + }
|
| + virtual void TransferComplete(HttpFetcher* fetcher, bool successful) {
|
| + EXPECT_EQ(expected_response_code_ != 0, successful);
|
| + if (expected_response_code_ != 0)
|
| + EXPECT_EQ(expected_response_code_, fetcher->http_response_code());
|
| + g_main_loop_quit(loop_);
|
| + }
|
| + int expected_response_code_;
|
| + string data;
|
| + GMainLoop* loop_;
|
| +};
|
| +
|
| +void MultiTest(HttpFetcher* fetcher_in,
|
| + const string& url,
|
| + const MultiHttpFetcher<LibcurlHttpFetcher>::RangesVect& ranges,
|
| + const string& expected_prefix,
|
| + off_t expected_size,
|
| + int expected_response_code) {
|
| + GMainLoop* loop = g_main_loop_new(g_main_context_default(), FALSE);
|
| + {
|
| + MultiHttpFetcherTestDelegate delegate(expected_response_code);
|
| + delegate.loop_ = loop;
|
| + scoped_ptr<HttpFetcher> fetcher(fetcher_in);
|
| + MultiHttpFetcher<LibcurlHttpFetcher>* multi_fetcher =
|
| + dynamic_cast<MultiHttpFetcher<LibcurlHttpFetcher>*>(fetcher.get());
|
| + ASSERT_TRUE(multi_fetcher);
|
| + multi_fetcher->set_ranges(ranges);
|
| + fetcher->set_delegate(&delegate);
|
| +
|
| + StartTransferArgs start_xfer_args = {fetcher.get(), url};
|
| +
|
| + g_timeout_add(0, StartTransfer, &start_xfer_args);
|
| + g_main_loop_run(loop);
|
| +
|
| + EXPECT_EQ(expected_size, delegate.data.size());
|
| + EXPECT_EQ(expected_prefix,
|
| + string(delegate.data.data(), expected_prefix.size()));
|
| + }
|
| + g_main_loop_unref(loop);
|
| +}
|
| +} // namespace {}
|
| +
|
| +TYPED_TEST(HttpFetcherTest, MultiHttpFetcherSimplTest) {
|
| + if (!this->IsMulti())
|
| + return;
|
| + typename TestFixture::HttpServer server;
|
| + ASSERT_TRUE(server.started_);
|
| +
|
| + MultiHttpFetcher<LibcurlHttpFetcher>::RangesVect ranges;
|
| + ranges.push_back(make_pair(0, 25));
|
| + ranges.push_back(make_pair(99, -1));
|
| + MultiTest(this->NewLargeFetcher(),
|
| + this->BigUrl(),
|
| + ranges,
|
| + "abcdefghijabcdefghijabcdejabcdefghijabcdef",
|
| + kBigSize - (99 - 25),
|
| + 206);
|
| +}
|
| +
|
| +TYPED_TEST(HttpFetcherTest, MultiHttpFetcherLengthLimitTest) {
|
| + if (!this->IsMulti())
|
| + return;
|
| + typename TestFixture::HttpServer server;
|
| + ASSERT_TRUE(server.started_);
|
| +
|
| + MultiHttpFetcher<LibcurlHttpFetcher>::RangesVect ranges;
|
| + ranges.push_back(make_pair(0, 24));
|
| + MultiTest(this->NewLargeFetcher(),
|
| + this->BigUrl(),
|
| + ranges,
|
| + "abcdefghijabcdefghijabcd",
|
| + 24,
|
| + 200);
|
| +}
|
| +
|
| +TYPED_TEST(HttpFetcherTest, MultiHttpFetcherMultiEndTest) {
|
| + if (!this->IsMulti())
|
| + return;
|
| + typename TestFixture::HttpServer server;
|
| + ASSERT_TRUE(server.started_);
|
| +
|
| + MultiHttpFetcher<LibcurlHttpFetcher>::RangesVect ranges;
|
| + ranges.push_back(make_pair(kBigSize - 2, -1));
|
| + ranges.push_back(make_pair(kBigSize - 3, -1));
|
| + MultiTest(this->NewLargeFetcher(),
|
| + this->BigUrl(),
|
| + ranges,
|
| + "ijhij",
|
| + 5,
|
| + 206);
|
| +}
|
| +
|
| +TYPED_TEST(HttpFetcherTest, MultiHttpFetcherInsufficientTest) {
|
| + if (!this->IsMulti())
|
| + return;
|
| + typename TestFixture::HttpServer server;
|
| + ASSERT_TRUE(server.started_);
|
| +
|
| + MultiHttpFetcher<LibcurlHttpFetcher>::RangesVect ranges;
|
| + ranges.push_back(make_pair(kBigSize - 2, 4));
|
| + for (int i = 0; i < 2; ++i) {
|
| + MultiTest(this->NewLargeFetcher(),
|
| + this->BigUrl(),
|
| + ranges,
|
| + "ij",
|
| + 2,
|
| + 0);
|
| + ranges.push_back(make_pair(0, 5));
|
| + }
|
| +}
|
| +
|
| } // namespace chromeos_update_engine
|
|
|