| OLD | NEW |
| 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 | 6 |
| 7 #include <string> | 7 #include <string> |
| 8 #include <utility> | 8 #include <utility> |
| 9 #include <vector> | 9 #include <vector> |
| 10 | 10 |
| 11 #include <base/logging.h> | 11 #include <base/logging.h> |
| 12 #include <base/scoped_ptr.h> | 12 #include <base/scoped_ptr.h> |
| 13 #include <base/string_util.h> | 13 #include <base/string_util.h> |
| 14 #include <glib.h> | 14 #include <glib.h> |
| 15 #include <gtest/gtest.h> | 15 #include <gtest/gtest.h> |
| 16 | 16 |
| 17 #include "update_engine/libcurl_http_fetcher.h" | 17 #include "update_engine/libcurl_http_fetcher.h" |
| 18 #include "update_engine/mock_http_fetcher.h" | 18 #include "update_engine/mock_http_fetcher.h" |
| 19 #include "update_engine/multi_http_fetcher.h" | 19 #include "update_engine/multi_range_http_fetcher.h" |
| 20 #include "update_engine/proxy_resolver.h" | 20 #include "update_engine/proxy_resolver.h" |
| 21 | 21 |
| 22 using std::make_pair; | 22 using std::make_pair; |
| 23 using std::pair; |
| 23 using std::string; | 24 using std::string; |
| 24 using std::vector; | 25 using std::vector; |
| 25 | 26 |
| 26 namespace chromeos_update_engine { | 27 namespace chromeos_update_engine { |
| 27 | 28 |
| 28 namespace { | 29 namespace { |
| 29 // WARNING, if you update these, you must also update test_http_server.cc. | 30 // WARNING, if you update these, you must also update test_http_server.cc. |
| 30 const char* const kServerPort = "8088"; | 31 const char* const kServerPort = "8088"; |
| 31 const int kBigSize = 100000; | 32 const int kBigSize = 100000; |
| 32 string LocalServerUrlForPath(const string& path) { | 33 string LocalServerUrlForPath(const string& path) { |
| (...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 163 bool IsMulti() const { return false; } | 164 bool IsMulti() const { return false; } |
| 164 typedef PythonHttpServer HttpServer; | 165 typedef PythonHttpServer HttpServer; |
| 165 void IgnoreServerAborting(HttpServer* server) const { | 166 void IgnoreServerAborting(HttpServer* server) const { |
| 166 PythonHttpServer *pyserver = reinterpret_cast<PythonHttpServer*>(server); | 167 PythonHttpServer *pyserver = reinterpret_cast<PythonHttpServer*>(server); |
| 167 pyserver->validate_quit_ = false; | 168 pyserver->validate_quit_ = false; |
| 168 } | 169 } |
| 169 DirectProxyResolver proxy_resolver_; | 170 DirectProxyResolver proxy_resolver_; |
| 170 }; | 171 }; |
| 171 | 172 |
| 172 template <> | 173 template <> |
| 173 class HttpFetcherTest<MultiHttpFetcher<LibcurlHttpFetcher> > | 174 class HttpFetcherTest<MultiRangeHTTPFetcher> |
| 174 : public HttpFetcherTest<LibcurlHttpFetcher> { | 175 : public HttpFetcherTest<LibcurlHttpFetcher> { |
| 175 public: | 176 public: |
| 176 HttpFetcher* NewLargeFetcher() { | 177 HttpFetcher* NewLargeFetcher() { |
| 177 MultiHttpFetcher<LibcurlHttpFetcher> *ret = | 178 ProxyResolver* resolver = |
| 178 new MultiHttpFetcher<LibcurlHttpFetcher>( | 179 reinterpret_cast<ProxyResolver*>(&proxy_resolver_); |
| 179 reinterpret_cast<ProxyResolver*>(&proxy_resolver_)); | 180 MultiRangeHTTPFetcher *ret = |
| 180 MultiHttpFetcher<LibcurlHttpFetcher>::RangesVect | 181 new MultiRangeHTTPFetcher(new LibcurlHttpFetcher(resolver)); |
| 181 ranges(1, make_pair(0, -1)); | 182 ret->ClearRanges(); |
| 182 ret->set_ranges(ranges); | 183 ret->AddRange(0, -1); |
| 183 // Speed up test execution. | 184 // Speed up test execution. |
| 184 ret->set_idle_seconds(1); | 185 ret->set_idle_seconds(1); |
| 185 ret->set_retry_seconds(1); | 186 ret->set_retry_seconds(1); |
| 186 ret->SetConnectionAsExpensive(false); | 187 ret->SetConnectionAsExpensive(false); |
| 187 ret->SetBuildType(false); | 188 ret->SetBuildType(false); |
| 188 return ret; | 189 return ret; |
| 189 } | 190 } |
| 190 bool IsMulti() const { return true; } | 191 bool IsMulti() const { return true; } |
| 191 DirectProxyResolver proxy_resolver_; | 192 DirectProxyResolver proxy_resolver_; |
| 192 }; | 193 }; |
| 193 | 194 |
| 194 typedef ::testing::Types<LibcurlHttpFetcher, | 195 typedef ::testing::Types<LibcurlHttpFetcher, |
| 195 MockHttpFetcher, | 196 MockHttpFetcher, |
| 196 MultiHttpFetcher<LibcurlHttpFetcher> > | 197 MultiRangeHTTPFetcher> |
| 197 HttpFetcherTestTypes; | 198 HttpFetcherTestTypes; |
| 198 TYPED_TEST_CASE(HttpFetcherTest, HttpFetcherTestTypes); | 199 TYPED_TEST_CASE(HttpFetcherTest, HttpFetcherTestTypes); |
| 199 | 200 |
| 200 namespace { | 201 namespace { |
| 201 class HttpFetcherTestDelegate : public HttpFetcherDelegate { | 202 class HttpFetcherTestDelegate : public HttpFetcherDelegate { |
| 202 public: | 203 public: |
| 203 virtual void ReceivedBytes(HttpFetcher* fetcher, | 204 virtual void ReceivedBytes(HttpFetcher* fetcher, |
| 204 const char* bytes, int length) { | 205 const char* bytes, int length) { |
| 205 char str[length + 1]; | 206 char str[length + 1]; |
| 206 memset(str, 0, length + 1); | 207 memset(str, 0, length + 1); |
| (...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 337 ADD_FAILURE(); // We should never get here | 338 ADD_FAILURE(); // We should never get here |
| 338 g_main_loop_quit(loop_); | 339 g_main_loop_quit(loop_); |
| 339 } | 340 } |
| 340 virtual void TransferTerminated(HttpFetcher* fetcher) { | 341 virtual void TransferTerminated(HttpFetcher* fetcher) { |
| 341 EXPECT_EQ(fetcher, fetcher_.get()); | 342 EXPECT_EQ(fetcher, fetcher_.get()); |
| 342 EXPECT_FALSE(once_); | 343 EXPECT_FALSE(once_); |
| 343 EXPECT_TRUE(callback_once_); | 344 EXPECT_TRUE(callback_once_); |
| 344 callback_once_ = false; | 345 callback_once_ = false; |
| 345 // |fetcher| can be destroyed during this callback. | 346 // |fetcher| can be destroyed during this callback. |
| 346 fetcher_.reset(NULL); | 347 fetcher_.reset(NULL); |
| 347 } | 348 } |
| 348 void TerminateTransfer() { | 349 void TerminateTransfer() { |
| 349 CHECK(once_); | 350 CHECK(once_); |
| 350 once_ = false; | 351 once_ = false; |
| 351 fetcher_->TerminateTransfer(); | 352 fetcher_->TerminateTransfer(); |
| 352 } | 353 } |
| 353 void EndLoop() { | 354 void EndLoop() { |
| 354 g_main_loop_quit(loop_); | 355 g_main_loop_quit(loop_); |
| 355 } | 356 } |
| 356 bool once_; | 357 bool once_; |
| 357 bool callback_once_; | 358 bool callback_once_; |
| (...skipping 286 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 644 ADD_FAILURE(); | 645 ADD_FAILURE(); |
| 645 } | 646 } |
| 646 scoped_ptr<HttpFetcher> fetcher_; | 647 scoped_ptr<HttpFetcher> fetcher_; |
| 647 int expected_response_code_; | 648 int expected_response_code_; |
| 648 string data; | 649 string data; |
| 649 GMainLoop* loop_; | 650 GMainLoop* loop_; |
| 650 }; | 651 }; |
| 651 | 652 |
| 652 void MultiTest(HttpFetcher* fetcher_in, | 653 void MultiTest(HttpFetcher* fetcher_in, |
| 653 const string& url, | 654 const string& url, |
| 654 const MultiHttpFetcher<LibcurlHttpFetcher>::RangesVect& ranges, | 655 const vector<pair<off_t, off_t> >& ranges, |
| 655 const string& expected_prefix, | 656 const string& expected_prefix, |
| 656 off_t expected_size, | 657 off_t expected_size, |
| 657 int expected_response_code) { | 658 int expected_response_code) { |
| 658 GMainLoop* loop = g_main_loop_new(g_main_context_default(), FALSE); | 659 GMainLoop* loop = g_main_loop_new(g_main_context_default(), FALSE); |
| 659 { | 660 { |
| 660 MultiHttpFetcherTestDelegate delegate(expected_response_code); | 661 MultiHttpFetcherTestDelegate delegate(expected_response_code); |
| 661 delegate.loop_ = loop; | 662 delegate.loop_ = loop; |
| 662 delegate.fetcher_.reset(fetcher_in); | 663 delegate.fetcher_.reset(fetcher_in); |
| 663 MultiHttpFetcher<LibcurlHttpFetcher>* multi_fetcher = | 664 MultiRangeHTTPFetcher* multi_fetcher = |
| 664 dynamic_cast<MultiHttpFetcher<LibcurlHttpFetcher>*>(fetcher_in); | 665 dynamic_cast<MultiRangeHTTPFetcher*>(fetcher_in); |
| 665 ASSERT_TRUE(multi_fetcher); | 666 ASSERT_TRUE(multi_fetcher); |
| 666 multi_fetcher->set_ranges(ranges); | 667 multi_fetcher->ClearRanges(); |
| 668 for (vector<pair<off_t, off_t> >::const_iterator it = ranges.begin(), |
| 669 e = ranges.end(); it != e; ++it) { |
| 670 LOG(INFO) << "Adding range"; |
| 671 multi_fetcher->AddRange(it->first, it->second); |
| 672 } |
| 667 multi_fetcher->SetConnectionAsExpensive(false); | 673 multi_fetcher->SetConnectionAsExpensive(false); |
| 668 multi_fetcher->SetBuildType(false); | 674 multi_fetcher->SetBuildType(false); |
| 669 multi_fetcher->set_delegate(&delegate); | 675 multi_fetcher->set_delegate(&delegate); |
| 670 | 676 |
| 671 StartTransferArgs start_xfer_args = {multi_fetcher, url}; | 677 StartTransferArgs start_xfer_args = {multi_fetcher, url}; |
| 672 | 678 |
| 673 g_timeout_add(0, StartTransfer, &start_xfer_args); | 679 g_timeout_add(0, StartTransfer, &start_xfer_args); |
| 674 g_main_loop_run(loop); | 680 g_main_loop_run(loop); |
| 675 | 681 |
| 676 EXPECT_EQ(expected_size, delegate.data.size()); | 682 EXPECT_EQ(expected_size, delegate.data.size()); |
| 677 EXPECT_EQ(expected_prefix, | 683 EXPECT_EQ(expected_prefix, |
| 678 string(delegate.data.data(), expected_prefix.size())); | 684 string(delegate.data.data(), expected_prefix.size())); |
| 679 } | 685 } |
| 680 g_main_loop_unref(loop); | 686 g_main_loop_unref(loop); |
| 681 } | 687 } |
| 682 } // namespace {} | 688 } // namespace {} |
| 683 | 689 |
| 684 TYPED_TEST(HttpFetcherTest, MultiHttpFetcherSimpleTest) { | 690 TYPED_TEST(HttpFetcherTest, MultiHttpFetcherSimpleTest) { |
| 685 if (!this->IsMulti()) | 691 if (!this->IsMulti()) |
| 686 return; | 692 return; |
| 687 typename TestFixture::HttpServer server; | 693 typename TestFixture::HttpServer server; |
| 688 ASSERT_TRUE(server.started_); | 694 ASSERT_TRUE(server.started_); |
| 689 | 695 |
| 690 MultiHttpFetcher<LibcurlHttpFetcher>::RangesVect ranges; | 696 vector<pair<off_t, off_t> > ranges; |
| 691 ranges.push_back(make_pair(0, 25)); | 697 ranges.push_back(make_pair(0, 25)); |
| 692 ranges.push_back(make_pair(99, -1)); | 698 ranges.push_back(make_pair(99, -1)); |
| 693 MultiTest(this->NewLargeFetcher(), | 699 MultiTest(this->NewLargeFetcher(), |
| 694 this->BigUrl(), | 700 this->BigUrl(), |
| 695 ranges, | 701 ranges, |
| 696 "abcdefghijabcdefghijabcdejabcdefghijabcdef", | 702 "abcdefghijabcdefghijabcdejabcdefghijabcdef", |
| 697 kBigSize - (99 - 25), | 703 kBigSize - (99 - 25), |
| 698 206); | 704 206); |
| 699 } | 705 } |
| 700 | 706 |
| 701 TYPED_TEST(HttpFetcherTest, MultiHttpFetcherLengthLimitTest) { | 707 TYPED_TEST(HttpFetcherTest, MultiHttpFetcherLengthLimitTest) { |
| 702 if (!this->IsMulti()) | 708 if (!this->IsMulti()) |
| 703 return; | 709 return; |
| 704 typename TestFixture::HttpServer server; | 710 typename TestFixture::HttpServer server; |
| 705 ASSERT_TRUE(server.started_); | 711 ASSERT_TRUE(server.started_); |
| 706 | 712 |
| 707 MultiHttpFetcher<LibcurlHttpFetcher>::RangesVect ranges; | 713 vector<pair<off_t, off_t> > ranges; |
| 708 ranges.push_back(make_pair(0, 24)); | 714 ranges.push_back(make_pair(0, 24)); |
| 709 MultiTest(this->NewLargeFetcher(), | 715 MultiTest(this->NewLargeFetcher(), |
| 710 this->BigUrl(), | 716 this->BigUrl(), |
| 711 ranges, | 717 ranges, |
| 712 "abcdefghijabcdefghijabcd", | 718 "abcdefghijabcdefghijabcd", |
| 713 24, | 719 24, |
| 714 200); | 720 200); |
| 715 } | 721 } |
| 716 | 722 |
| 717 TYPED_TEST(HttpFetcherTest, MultiHttpFetcherMultiEndTest) { | 723 TYPED_TEST(HttpFetcherTest, MultiHttpFetcherMultiEndTest) { |
| 718 if (!this->IsMulti()) | 724 if (!this->IsMulti()) |
| 719 return; | 725 return; |
| 720 typename TestFixture::HttpServer server; | 726 typename TestFixture::HttpServer server; |
| 721 ASSERT_TRUE(server.started_); | 727 ASSERT_TRUE(server.started_); |
| 722 | 728 |
| 723 MultiHttpFetcher<LibcurlHttpFetcher>::RangesVect ranges; | 729 vector<pair<off_t, off_t> > ranges; |
| 724 ranges.push_back(make_pair(kBigSize - 2, -1)); | 730 ranges.push_back(make_pair(kBigSize - 2, -1)); |
| 725 ranges.push_back(make_pair(kBigSize - 3, -1)); | 731 ranges.push_back(make_pair(kBigSize - 3, -1)); |
| 726 MultiTest(this->NewLargeFetcher(), | 732 MultiTest(this->NewLargeFetcher(), |
| 727 this->BigUrl(), | 733 this->BigUrl(), |
| 728 ranges, | 734 ranges, |
| 729 "ijhij", | 735 "ijhij", |
| 730 5, | 736 5, |
| 731 206); | 737 206); |
| 732 } | 738 } |
| 733 | 739 |
| 734 TYPED_TEST(HttpFetcherTest, MultiHttpFetcherInsufficientTest) { | 740 TYPED_TEST(HttpFetcherTest, MultiHttpFetcherInsufficientTest) { |
| 735 if (!this->IsMulti()) | 741 if (!this->IsMulti()) |
| 736 return; | 742 return; |
| 737 typename TestFixture::HttpServer server; | 743 typename TestFixture::HttpServer server; |
| 738 ASSERT_TRUE(server.started_); | 744 ASSERT_TRUE(server.started_); |
| 739 | 745 |
| 740 MultiHttpFetcher<LibcurlHttpFetcher>::RangesVect ranges; | 746 vector<pair<off_t, off_t> > ranges; |
| 741 ranges.push_back(make_pair(kBigSize - 2, 4)); | 747 ranges.push_back(make_pair(kBigSize - 2, 4)); |
| 742 for (int i = 0; i < 2; ++i) { | 748 for (int i = 0; i < 2; ++i) { |
| 749 LOG(INFO) << "i = " << i; |
| 743 MultiTest(this->NewLargeFetcher(), | 750 MultiTest(this->NewLargeFetcher(), |
| 744 this->BigUrl(), | 751 this->BigUrl(), |
| 745 ranges, | 752 ranges, |
| 746 "ij", | 753 "ij", |
| 747 2, | 754 2, |
| 748 0); | 755 0); |
| 749 ranges.push_back(make_pair(0, 5)); | 756 ranges.push_back(make_pair(0, 5)); |
| 750 } | 757 } |
| 751 } | 758 } |
| 752 | 759 |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 796 StartTransferArgs start_xfer_args = | 803 StartTransferArgs start_xfer_args = |
| 797 { fetcher.get(), LocalServerUrlForPath(this->SmallUrl()) }; | 804 { fetcher.get(), LocalServerUrlForPath(this->SmallUrl()) }; |
| 798 | 805 |
| 799 g_timeout_add(0, StartTransfer, &start_xfer_args); | 806 g_timeout_add(0, StartTransfer, &start_xfer_args); |
| 800 g_main_loop_run(loop); | 807 g_main_loop_run(loop); |
| 801 g_main_loop_unref(loop); | 808 g_main_loop_unref(loop); |
| 802 } | 809 } |
| 803 } | 810 } |
| 804 | 811 |
| 805 } // namespace chromeos_update_engine | 812 } // namespace chromeos_update_engine |
| OLD | NEW |