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 |